diff --git a/sw/cheri_toolchain.cmake b/sw/cheri_toolchain.cmake index e084f1140..5d6df67f8 100644 --- a/sw/cheri_toolchain.cmake +++ b/sw/cheri_toolchain.cmake @@ -32,14 +32,14 @@ set(CMAKE_CXX_STANDARD_REQUIRED TRUE) set(LDS_DIR "${CMAKE_SOURCE_DIR}/device/lib/boot") string(CONCAT CMAKE_CXX_FLAGS_INIT - "-std=c++20 -O0 -g" + "-std=c++20 -O1 -g" " -ffreestanding -static" " -fno-builtin -fno-exceptions -fno-c++-static-destructors -fno-rtti" " -Wall -Wextra" ) string(CONCAT CMAKE_C_FLAGS_INIT - "-std=c99 -O0 -g" + "-std=c99 -O1 -g" " -ffreestanding -static" " -fno-builtin" " -Wall -Wextra" 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/sw/device/lib/hal/spi_device.c b/sw/device/lib/hal/spi_device.c index 6f21cc0bb..1ad923cd6 100644 --- a/sw/device/lib/hal/spi_device.c +++ b/sw/device/lib/hal/spi_device.c @@ -8,256 +8,267 @@ #include #include -bool spi_device_interrupt_is_pending(spi_device_t spi_device, uint8_t intr_id) +bool spi_device_interrupt_any_pending(spi_device_t spi_device, spi_device_intr intrs) { - if (intr_id > SPI_DEVICE_MAX_INTR) { - return false; - } - return ((DEV_READ(spi_device + SPI_DEVICE_INTR_STATE_REG) & (1 << intr_id)) != 0); + return (VOLATILE_READ(spi_device->intr_state) & intrs) != 0u; } -void spi_device_interrupt_clear(spi_device_t spi_device, uint8_t intr_id) +void spi_device_interrupt_clear(spi_device_t spi_device, spi_device_intr intrs) { - if (intr_id <= SPI_DEVICE_MAX_INTR) { - DEV_WRITE(spi_device + SPI_DEVICE_INTR_STATE_REG, 1 << intr_id); - } + VOLATILE_WRITE(spi_device->intr_state, intrs); } -void spi_device_interrupt_disable_all(spi_device_t spi_device) +void spi_device_interrupt_enable_write(spi_device_t spi_device, spi_device_intr intrs) { - DEV_WRITE(spi_device + SPI_DEVICE_INTR_ENABLE_REG, 0); + VOLATILE_WRITE(spi_device->intr_enable, intrs); } -void spi_device_interrupt_enable(spi_device_t spi_device, uint8_t intr_id) +void spi_device_interrupt_enable_set(spi_device_t spi_device, spi_device_intr intrs) { - if (intr_id <= SPI_DEVICE_MAX_INTR) { - DEV_WRITE(spi_device + SPI_DEVICE_INTR_ENABLE_REG, - DEV_READ(spi_device + SPI_DEVICE_INTR_ENABLE_REG) | (1 << intr_id)); - } + spi_device_intr intr_enable = VOLATILE_READ(spi_device->intr_enable); + intr_enable |= intrs; + VOLATILE_WRITE(spi_device->intr_enable, intr_enable); } -void spi_device_interrupt_disable(spi_device_t spi_device, uint8_t intr_id) +void spi_device_interrupt_enable_clear(spi_device_t spi_device, spi_device_intr intrs) { - if (intr_id <= SPI_DEVICE_MAX_INTR) { - DEV_WRITE(spi_device + SPI_DEVICE_INTR_ENABLE_REG, - DEV_READ(spi_device + SPI_DEVICE_INTR_ENABLE_REG) & ~(1 << intr_id)); - } + spi_device_intr intr_enable = VOLATILE_READ(spi_device->intr_enable); + intr_enable &= ~intrs; + VOLATILE_WRITE(spi_device->intr_enable, intr_enable); } -void spi_device_interrupt_trigger(spi_device_t spi_device, uint8_t intr_id) +void spi_device_interrupt_force(spi_device_t spi_device, spi_device_intr intrs) { - if (intr_id <= SPI_DEVICE_MAX_INTR) { - DEV_WRITE(spi_device + SPI_DEVICE_INTR_TEST_REG, 1 << intr_id); - } + VOLATILE_WRITE(spi_device->intr_test, intrs); } void spi_device_enable_set(spi_device_t spi_device, bool enable) { - DEV_WRITE(spi_device + SPI_DEVICE_CTRL_REG, enable << SPI_DEVICE_CTRL_MODE_OFFSET); + spi_device_control ctrl = { .mode = enable ? 1u : 0u }; + VOLATILE_WRITE(spi_device->control, ctrl); } void spi_device_4b_addr_mode_enable_set(spi_device_t spi_device, bool enable) { - DEV_WRITE(spi_device + SPI_DEVICE_ADDR_MODE_REG, (uint32_t)enable); + spi_device_addr_mode addr_mode = { .addr_4b_en = enable }; + VOLATILE_WRITE(spi_device->addr_mode, addr_mode); // Wait for change to take effect - while (DEV_READ(spi_device + SPI_DEVICE_ADDR_MODE_REG) & SPI_DEVICE_ADDR_MODE_PENDING_MASK) { - } + // while (VOLATILE_READ(spi_device->addr_mode).pending) { + // } } bool spi_device_4b_addr_mode_enable_get(spi_device_t spi_device) { - return ((DEV_READ(spi_device + SPI_DEVICE_ADDR_MODE_REG) & SPI_DEVICE_ADDR_MODE_4B_EN_MASK) == - 1); + return VOLATILE_READ(spi_device->addr_mode).addr_4b_en; } void spi_device_flash_status_set(spi_device_t spi_device, uint32_t flash_status) { - DEV_WRITE(spi_device + SPI_DEVICE_FLASH_STATUS_REG, flash_status); + spi_device_flash_status s; + __builtin_memcpy(&s, &flash_status, sizeof(s)); + VOLATILE_WRITE(spi_device->flash_status, s); } uint32_t spi_device_flash_status_get(spi_device_t spi_device) { - return DEV_READ(spi_device + SPI_DEVICE_FLASH_STATUS_REG); + spi_device_flash_status s = VOLATILE_READ(spi_device->flash_status); + uint32_t raw; + __builtin_memcpy(&raw, &s, sizeof(raw)); + return raw; } void spi_device_jedec_cc_set(spi_device_t spi_device, uint8_t cc, uint8_t num_cc) { - DEV_WRITE(spi_device + SPI_DEVICE_JEDEC_CC_REG, - ((uint32_t)cc << SPI_DEVICE_JEDEC_CC) | - ((uint32_t)num_cc << SPI_DEVICE_JEDEC_NUM_CC)); + spi_device_jedec_cc jedec_cc = { .cc = cc, .num_cc = num_cc }; + VOLATILE_WRITE(spi_device->jedec_cc, jedec_cc); } uint16_t spi_device_jedec_cc_get(spi_device_t spi_device) { - return (uint16_t)DEV_READ(spi_device + SPI_DEVICE_JEDEC_CC_REG); + spi_device_jedec_cc jedec_cc = VOLATILE_READ(spi_device->jedec_cc); + return (uint16_t)(jedec_cc.cc | ((uint16_t)jedec_cc.num_cc << 8)); } void spi_device_jedec_id_set_raw(spi_device_t spi_device, uint32_t data) { - DEV_WRITE(spi_device + SPI_DEVICE_JEDEC_ID_REG, data); + spi_device_jedec_id jedec_id; + __builtin_memcpy(&jedec_id, &data, sizeof(jedec_id)); + VOLATILE_WRITE(spi_device->jedec_id, jedec_id); } void spi_device_jedec_id_set(spi_device_t spi_device, bool rom_bootstrap, uint8_t chip_rev, uint8_t chip_gen, uint8_t density, uint8_t manufacturer_id) { - uint32_t reg = ((uint32_t)rom_bootstrap) << SPI_DEVICE_ROM_BOOTSTRAP; - reg = reg | (((uint32_t)chip_rev & SPI_DEVICE_CHIP_REV_MASK) << SPI_DEVICE_CHIP_REV); - reg = reg | (((uint32_t)chip_gen & SPI_DEVICE_CHIP_GEN_MASK) << SPI_DEVICE_CHIP_GEN); - reg = reg | (((uint32_t)density) << SPI_DEVICE_DENSITY); - reg = reg | (((uint32_t)manufacturer_id) << SPI_DEVICE_MANUFACTURER_ID); - spi_device_jedec_id_set_raw(spi_device, reg); + uint16_t id = (uint16_t)((chip_rev & 0x7u) | ((uint16_t)rom_bootstrap << 3) | + ((uint16_t)(chip_gen & 0xFu) << 4) | ((uint16_t)density << 8)); + spi_device_jedec_id jedec_id = { .id = id, .mf = manufacturer_id }; + VOLATILE_WRITE(spi_device->jedec_id, jedec_id); } uint32_t spi_device_jedec_id_get(spi_device_t spi_device) { - return DEV_READ(spi_device + SPI_DEVICE_JEDEC_ID_REG); + spi_device_jedec_id jedec_id = VOLATILE_READ(spi_device->jedec_id); + uint32_t raw; + __builtin_memcpy(&raw, &jedec_id, sizeof(raw)); + return raw; } void spi_device_mailbox_addr_set(spi_device_t spi_device, uint32_t addr) { - DEV_WRITE(spi_device + SPI_DEVICE_MAILBOX_ADDR_REG, addr); + VOLATILE_WRITE(spi_device->mailbox_addr, addr); } uint32_t spi_device_mailbox_addr_get(spi_device_t spi_device) { - return DEV_READ(spi_device + SPI_DEVICE_MAILBOX_ADDR_REG); + return VOLATILE_READ(spi_device->mailbox_addr); } uint32_t spi_device_upload_status_get(spi_device_t spi_device) { - return DEV_READ(spi_device + SPI_DEVICE_UPLOAD_STATUS_REG); + spi_device_upload_status s = VOLATILE_READ(spi_device->upload_status); + uint32_t raw; + __builtin_memcpy(&raw, &s, sizeof(raw)); + return raw; } uint32_t spi_device_upload_status2_get(spi_device_t spi_device) { - return DEV_READ(spi_device + SPI_DEVICE_UPLOAD_STATUS2_REG); + spi_device_upload_status2 s = VOLATILE_READ(spi_device->upload_status2); + uint32_t raw; + __builtin_memcpy(&raw, &s, sizeof(raw)); + return raw; } uint32_t spi_device_upload_cmdfifo_read(spi_device_t spi_device) { - return DEV_READ(spi_device + SPI_DEVICE_UPLOAD_CMDFIFO_REG); + spi_device_upload_cmdfifo s = VOLATILE_READ(spi_device->upload_cmdfifo); + uint32_t raw; + __builtin_memcpy(&raw, &s, sizeof(raw)); + return raw; } uint32_t spi_device_upload_addrfifo_read(spi_device_t spi_device) { - return DEV_READ(spi_device + SPI_DEVICE_UPLOAD_ADDRFIFO_REG); + return VOLATILE_READ(spi_device->upload_addrfifo); } -void spi_device_cmd_filter_set(spi_device_t spi_device, uint32_t offset, uint32_t data) +void spi_device_cmd_filter_set(spi_device_t spi_device, uint8_t idx, uint32_t data) { - if (offset < SPI_DEVICE_CMD_FILTER_0_REG || offset > SPI_DEVICE_CMD_FILTER_7_REG) { + if (idx >= 8) { return; } - - DEV_WRITE(spi_device + offset, data); + VOLATILE_WRITE(spi_device->cmd_filter[idx], data); } -uint32_t spi_device_cmd_filter_get(spi_device_t spi_device, uint32_t offset) +uint32_t spi_device_cmd_filter_get(spi_device_t spi_device, uint8_t idx) { - if (offset < SPI_DEVICE_CMD_FILTER_0_REG || offset > SPI_DEVICE_CMD_FILTER_7_REG) { + if (idx >= 8) { return 0; } - - return DEV_READ(spi_device + offset); + return VOLATILE_READ(spi_device->cmd_filter[idx]); } -void spi_device_cmd_info_set_raw(spi_device_t spi_device, uint32_t offset, uint32_t data) +void spi_device_cmd_info_set_raw(spi_device_t spi_device, uint8_t idx, uint32_t data) { - if (offset < SPI_DEVICE_CMD_INFO_0_REG || offset > SPI_DEVICE_CMD_INFO_23_REG) { + if (idx >= 24) { return; } - - DEV_WRITE(spi_device + offset, data); + spi_device_cmd_info cmd_info; + __builtin_memcpy(&cmd_info, &data, sizeof(cmd_info)); + VOLATILE_WRITE(spi_device->cmd_info[idx], cmd_info); } -void spi_device_cmd_info_set(spi_device_t spi_device, uint32_t offset, uint8_t opcode, +void spi_device_cmd_info_set(spi_device_t spi_device, uint8_t idx, uint8_t opcode, uint8_t addr_mode, uint8_t dummy_cycles, bool handled_in_sw) { - if (offset < SPI_DEVICE_CMD_INFO_0_REG || offset > SPI_DEVICE_CMD_INFO_23_REG) { + if (idx >= 24) { return; } - uint32_t reg = 0; - reg = reg | (opcode << SPI_DEVICE_CMD_OPCODE); - - reg = reg | ((addr_mode & SPI_DEVICE_CMD_ADDR_MODE_MASK) << SPI_DEVICE_CMD_ADDR_MODE); + spi_device_cmd_info cmd_info = { 0 }; + cmd_info.opcode = opcode; + cmd_info.addr_mode = addr_mode; if (dummy_cycles > 0) { - reg = reg | - (((dummy_cycles - 1) & SPI_DEVICE_CMD_DUMMY_SIZE_MASK) << SPI_DEVICE_CMD_DUMMY_SIZE); - reg = reg | (1 << SPI_DEVICE_CMD_DUMMY_EN); + cmd_info.dummy_size = dummy_cycles - 1; + cmd_info.dummy_en = 1; } if (handled_in_sw) { - reg = reg | (1 << SPI_DEVICE_CMD_UPLOAD); - reg = reg | (1 << SPI_DEVICE_CMD_BUSY); + cmd_info.upload = 1; + cmd_info.busy = 1; } - reg = reg | (1 << SPI_DEVICE_CMD_VALID); + cmd_info.valid = 1; - spi_device_cmd_info_set_raw(spi_device, offset, reg); + VOLATILE_WRITE(spi_device->cmd_info[idx], cmd_info); } -uint32_t spi_device_cmd_info_get(spi_device_t spi_device, uint32_t offset) +uint32_t spi_device_cmd_info_get(spi_device_t spi_device, uint8_t idx) { - if (offset < SPI_DEVICE_CMD_INFO_0_REG || offset > SPI_DEVICE_CMD_INFO_23_REG) { + if (idx >= 24) { return 0; } - - return DEV_READ(spi_device + offset); + spi_device_cmd_info cmd_info = VOLATILE_READ(spi_device->cmd_info[idx]); + uint32_t raw; + __builtin_memcpy(&raw, &cmd_info, sizeof(raw)); + return raw; } void spi_device_cmd_info_4b_enable_set_raw(spi_device_t spi_device, uint32_t data) { - DEV_WRITE(spi_device + SPI_DEVICE_CMD_INFO_EN4B_REG, data); + spi_device_cmd_info_en4b en4b; + __builtin_memcpy(&en4b, &data, sizeof(en4b)); + VOLATILE_WRITE(spi_device->cmd_info_en4b, en4b); } void spi_device_cmd_info_4b_enable_set(spi_device_t spi_device, uint8_t opcode) { - uint32_t reg = 0; - reg = reg | (opcode << SPI_DEVICE_CMD_OPCODE); - reg = reg | (1 << SPI_DEVICE_CMD_VALID); - - spi_device_cmd_info_4b_enable_set_raw(spi_device, reg); + spi_device_cmd_info_en4b en4b = { .opcode = opcode, .valid = 1 }; + VOLATILE_WRITE(spi_device->cmd_info_en4b, en4b); } void spi_device_cmd_info_write_enable_set_raw(spi_device_t spi_device, uint32_t data) { - DEV_WRITE(spi_device + SPI_DEVICE_CMD_INFO_WREN_REG, data); + spi_device_cmd_info_wren wren; + __builtin_memcpy(&wren, &data, sizeof(wren)); + VOLATILE_WRITE(spi_device->cmd_info_wren, wren); } void spi_device_cmd_info_write_enable_set(spi_device_t spi_device, uint8_t opcode) { - uint32_t reg = 0; - reg = reg | (opcode << SPI_DEVICE_CMD_OPCODE); - reg = reg | (1 << SPI_DEVICE_CMD_VALID); - - spi_device_cmd_info_write_enable_set_raw(spi_device, reg); + spi_device_cmd_info_wren wren = { .opcode = opcode, .valid = 1 }; + VOLATILE_WRITE(spi_device->cmd_info_wren, wren); } uint32_t spi_device_cmd_info_write_enable_get(spi_device_t spi_device) { - return DEV_READ(spi_device + SPI_DEVICE_CMD_INFO_WREN_REG); + spi_device_cmd_info_wren wren = VOLATILE_READ(spi_device->cmd_info_wren); + uint32_t raw; + __builtin_memcpy(&raw, &wren, sizeof(raw)); + return raw; } void spi_device_cmd_info_write_disable_set_raw(spi_device_t spi_device, uint32_t data) { - DEV_WRITE(spi_device + SPI_DEVICE_CMD_INFO_WRDI_REG, data); + spi_device_cmd_info_wrdi wrdi; + __builtin_memcpy(&wrdi, &data, sizeof(wrdi)); + VOLATILE_WRITE(spi_device->cmd_info_wrdi, wrdi); } void spi_device_cmd_info_write_disable_set(spi_device_t spi_device, uint8_t opcode) { - uint32_t reg = 0; - reg = reg | (opcode << SPI_DEVICE_CMD_OPCODE); - reg = reg | (1 << SPI_DEVICE_CMD_VALID); - - spi_device_cmd_info_write_disable_set_raw(spi_device, reg); + spi_device_cmd_info_wrdi wrdi = { .opcode = opcode, .valid = 1 }; + VOLATILE_WRITE(spi_device->cmd_info_wrdi, wrdi); } uint32_t spi_device_cmd_info_write_disable_get(spi_device_t spi_device) { - return DEV_READ(spi_device + SPI_DEVICE_CMD_INFO_WRDI_REG); + spi_device_cmd_info_wrdi wrdi = VOLATILE_READ(spi_device->cmd_info_wrdi); + uint32_t raw; + __builtin_memcpy(&raw, &wrdi, sizeof(raw)); + return raw; } bool spi_device_flash_read_buffer_write(spi_device_t spi_device, uint32_t offset, uint32_t data) @@ -270,8 +281,7 @@ bool spi_device_flash_read_buffer_write(spi_device_t spi_device, uint32_t offset if (offset >= SPI_DEVICE_READ_BUFFER_NUM_BYTES) { return false; } - DEV_WRITE(spi_device + SPI_DEVICE_EGRESS_BUFFER_OFFSET + SPI_DEVICE_READ_BUFFER_OFFSET + offset, - data); + spi_device->egress_buffer[offset / sizeof(uint32_t)] = data; return true; } @@ -285,53 +295,50 @@ uint32_t spi_device_flash_payload_buffer_read(spi_device_t spi_device, uint32_t if (offset >= SPI_DEVICE_PAYLOAD_AREA_NUM_BYTES) { return 0; } - return DEV_READ( - spi_device + SPI_DEVICE_INGRESS_BUFFER_OFFSET + SPI_DEVICE_PAYLOAD_AREA_OFFSET + offset); + return spi_device->ingress_buffer[offset / sizeof(uint32_t)]; } void spi_device_sfdp_table_init(spi_device_t spi_device) { // Prepare pointer to SFDP area in egress buffer - void *buf_ptr = spi_device + SPI_DEVICE_EGRESS_BUFFER_OFFSET + SPI_DEVICE_SFDP_AREA_OFFSET; + volatile uint32_t *buf_ptr = + &spi_device->egress_buffer[SPI_DEVICE_SFDP_AREA_OFFSET / sizeof(uint32_t)]; + volatile uint32_t *const buf_end = buf_ptr + SPI_DEVICE_SFDP_AREA_NUM_BYTES / sizeof(uint32_t); // clang-format off // Write SFDP header 1st word // [31: 0]: SFDP signature that indicates the presence of a SFDP table (JESD216F 6.2.1) - DEV_WRITE(buf_ptr, SPI_DEVICE_SFDP_SIGNATURE); - buf_ptr += sizeof(uint32_t); + *buf_ptr++ = SPI_DEVICE_SFDP_SIGNATURE; // Write SFDP header 2nd word // [ 7: 0]: SFDP minor revision number (JESD216F 6.2.2) // [15: 8]: SFDP major revision number (JESD216F 6.2.2) // [23:16]: Number of parameter headers, zero-based (JESD216F 6.2.2) // [31:24]: SFDP access protocol (JESD216F 6.2.3) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field( 7, 0, SPI_DEVICE_SFDP_MINOR_REVISION) | reg32_field(15, 8, SPI_DEVICE_SFDP_MAJOR_REVISION) | reg32_field(23, 16, SPI_DEVICE_SFDP_PARAM_COUNT) | - reg32_field(31, 24, SPI_DEVICE_SFDP_ACCESS_PROTOCOL)); - buf_ptr += sizeof(uint32_t); + reg32_field(31, 24, SPI_DEVICE_SFDP_ACCESS_PROTOCOL); // Write Basic Flash Parameters Table (BFPT) parameter header 1st word // [ 7: 0]: LSB of the parameter ID that indicates parameter table ownership and type (JESD216F 6.3.1, 6.3.3) // [15: 8]: Parameter table minor revision number (JESD216F 6.3.1) // [23:16]: Parameter table major revision number (JESD216F 6.3.1) // [31:24]: Length of the parameter table in words, one-based (JESD216F 6.3.1) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field( 7, 0, SPI_DEVICE_BFPT_PARAM_ID_LSB) | reg32_field(15, 8, SPI_DEVICE_BFPT_MINOR_REVISION) | reg32_field(23, 16, SPI_DEVICE_BFPT_MAJOR_REVISION) | - reg32_field(31, 24, SPI_DEVICE_BFPT_NUM_WORDS)); - buf_ptr += sizeof(uint32_t); + reg32_field(31, 24, SPI_DEVICE_BFPT_NUM_WORDS); // Write BFPT parameter header 2nd word // [23: 0]: Word-aligned byte offset of the corresponding parameter table from the start of the SFDP table (JESD216F 6.3.2) // [31:24]: MSB of the parameter ID that indicates parameter table ownership and type (JESD216F 6.3.2, 6.3.3) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(23, 0, 4) | - reg32_field(31, 24, SPI_DEVICE_BFPT_PARAM_ID_MSB)); - buf_ptr += sizeof(uint32_t); + reg32_field(31, 24, SPI_DEVICE_BFPT_PARAM_ID_MSB); // Note: Words below are numbered starting from 1 to match JESD216F. Some fields // that are not supported by OpenTitan are merged for the sake of conciseness. @@ -347,7 +354,7 @@ void spi_device_sfdp_table_init(spi_device_t spi_device) // [ 3: 3]: Volatile block protect bits (solely volatile: 0x1) // [ 2: 2]: Write granularity (buffer >= 64 B: 0x1) // [ 1: 0]: Block/sector erase sizes (uniform 4 KiB erase: 0x1) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(31, 23, UINT32_MAX) | reg32_field(22, 19, 0) | reg32_field(18, 17, 0x0) | @@ -357,69 +364,60 @@ void spi_device_sfdp_table_init(spi_device_t spi_device) reg32_field( 4, 4, 0x1) | reg32_field( 3, 3, 0x1) | reg32_field( 2, 2, 0x1) | - reg32_field( 1, 0, 0x1)); - buf_ptr += sizeof(uint32_t); + reg32_field( 1, 0, 0x1); // Write BFPT 2nd Word // [31:31]: Density greater than 2 Gib (0x0) // [30: 0]: Flash memory density in bits, zero-based (0x7fffff) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(31, 31, 0x0) | - reg32_field(30, 0, MOCHA_SPI_DEVICE_DENSITY_BITS - 1)); - buf_ptr += sizeof(uint32_t); + reg32_field(30, 0, MOCHA_SPI_DEVICE_DENSITY_BITS - 1); // Write BFPT 3rd Word // [31: 0]: Fast read (1S-4S-4S) (1S-1S-4S) (not supported, 0x0) - DEV_WRITE(buf_ptr, 0); - buf_ptr += sizeof(uint32_t); + *buf_ptr++ = 0; // Write BFPT 4th Word // [31: 0]: Fast read (1S-1S-2S) (1S-2S-2S) (not supported, 0x0) - DEV_WRITE(buf_ptr, 0); - buf_ptr += sizeof(uint32_t); + *buf_ptr++ = 0; // Write BFPT 5th Word // [31: 5]: Reserved (all 1s) // [ 4: 4]: Fast read (4S-4S-4S) support (not supported, 0x0) // [ 3: 1]: Reserved (all 1s) // [ 0: 0]: Fast read (2S-2S-2S) support (not supported, 0x0) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(31, 5, UINT32_MAX) | reg32_field( 4, 4, 0x0) | reg32_field( 3, 1, UINT32_MAX) | - reg32_field( 0, 0, 0x0)); - buf_ptr += sizeof(uint32_t); + reg32_field( 0, 0, 0x0); // Write BFPT 6th Word // [31:16]: Fast read (2S-2S-2S) (not supported, 0x0) // [15: 0]: Reserved (all 1s) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(31, 16, 0x0) | - reg32_field(15, 0, UINT32_MAX)); - buf_ptr += sizeof(uint32_t); + reg32_field(15, 0, UINT32_MAX); // Write BFPT 7th Word // [31:16]: Fast read (4S-4S-4S) (not supported, 0x0) // [15: 0]: Reserved (all 1s) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(31, 16, 0x0) | - reg32_field(15, 0, UINT32_MAX)); - buf_ptr += sizeof(uint32_t); + reg32_field(15, 0, UINT32_MAX); // Write BFPT 8th Word // [31:16]: Erase type 2 instruction and size (not supported, 0x0) // [15: 8]: Erase type 1 instruction (0x20) // [ 7: 0]: Erase type 1 size (4 KiB, 2^N bytes, N = 0x0c) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(31, 16, 0x0) | reg32_field(15, 8, SPI_DEVICE_OPCODE_SECTOR_ERASE) | - reg32_field( 7, 0, 0x0C)); - buf_ptr += sizeof(uint32_t); + reg32_field( 7, 0, 0x0C); // Write BFPT 9th Word // [31: 0]: Erase type 4 and 3 (not supported, 0x0) - DEV_WRITE(buf_ptr, 0); - buf_ptr += sizeof(uint32_t); + *buf_ptr++ = 0; // Write BFPT 10th Word // [31:11]: Erase 4,3,2 typical time (not supported, 0x0) @@ -429,12 +427,11 @@ void spi_device_sfdp_table_init(spi_device_t spi_device) // (8 + 1) * 16 ms = 144 ms // [ 3: 0]: Max erase time multiplier, zero-based (0x6) // formula: 2 * (multiplier + 1) * erase_time - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(31, 11, 0x0) | reg32_field(10, 9, 0x1) | reg32_field( 8, 4, 0x8) | - reg32_field( 3, 0, 0x6)); - buf_ptr += sizeof(uint32_t); + reg32_field( 3, 0, 0x6); // Write BFPT 11th Word // [31:31]: Reserved (all 1s) @@ -457,7 +454,7 @@ void spi_device_sfdp_table_init(spi_device_t spi_device) // [ 7: 4]: Page size, 2^N (0x8) // [ 3: 0]: Max program time multiplier, zero-based (0x0) // formula: 2 * (multiplier + 1) * program_time - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(31, 31, UINT32_MAX) | reg32_field(30, 29, 0x0) | reg32_field(28, 24, 0xB) | @@ -468,107 +465,92 @@ void spi_device_sfdp_table_init(spi_device_t spi_device) reg32_field(13, 13, 0x1) | reg32_field(12, 8, 0xB) | reg32_field( 7, 4, 0x8) | - reg32_field( 3, 0, 0x0)); - buf_ptr += sizeof(uint32_t); + reg32_field( 3, 0, 0x0); // Write BFPT 12th Word // [31:31]: Suspend/Resume supported (not supported, 0x1) // [30: 9]: Suspend/Resume latencies for erase & program (not supported, 0x0) // [ 8: 8]: Reserved (all 1s) // [ 7: 0]: Prohibited ops during suspend (not supported, 0x0) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(31, 31, 0x1) | reg32_field(30, 9, 0x0) | reg32_field( 8, 8, UINT32_MAX) | - reg32_field( 7, 0, 0x0)); - buf_ptr += sizeof(uint32_t); + reg32_field( 7, 0, 0x0); // Write BFPT 13th Word // [31: 0]: Erase/program suspend/resume instructions (not supported, 0x0) - DEV_WRITE(buf_ptr, 0); - buf_ptr += sizeof(uint32_t); + *buf_ptr++ = 0; // Write BFPT 14th Word // [31:31]: Deep powerdown support (not supported, 0x1) // [30: 8]: Deep powerdown instructions and delay (not supported, 0x0) // [ 7: 2]: Busy polling (bit 0 using 0x05 instruction, 0x1) // [ 1: 0]: Reserved (all 1s) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(31, 31, 0x1) | reg32_field(30, 8, 0x0) | reg32_field( 7, 2, 0x1) | - reg32_field( 1, 0, UINT32_MAX)); - buf_ptr += sizeof(uint32_t); + reg32_field( 1, 0, UINT32_MAX); // Write BFPT 15th Word // [31:24]: Reserved (all 1s) // [23: 0]: Hold, QE, (4S-4S-4S), 0-4-4 (not supported, 0x0) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(31, 24, UINT32_MAX) | - reg32_field(23, 0, 0x0)); - buf_ptr += sizeof(uint32_t); + reg32_field(23, 0, 0x0); // Write BFPT 16th Word // [31:14]: 4-Byte addressing (not supported, 0x0) // [13: 8]: Soft-reset (0x66/0x99 sequence, 0x10) // [ 7: 7]: Reserved // [ 6: 0]: Status register (read-only, 0x0) - DEV_WRITE(buf_ptr, + *buf_ptr++ = reg32_field(31, 14, 0x0) | reg32_field(13, 8, 0x10) | reg32_field( 7, 7, UINT32_MAX) | - reg32_field( 6, 0, 0x0)); - buf_ptr += sizeof(uint32_t); + reg32_field( 6, 0, 0x0); // Write BFPT 17th Word // [31: 0]: Fast read (1S-8S-8S) (1S-1S-8S) (not supported, 0x0) - DEV_WRITE(buf_ptr, 0); - buf_ptr += sizeof(uint32_t); + *buf_ptr++ = 0; // Write BFPT 18th Word // [31, 0]: Data strobe, SPI protocol reset, etc. (not supported, 0x0) // // Note: Reserved fields of this word should be 0 (JESD216F 6.4.21). - DEV_WRITE(buf_ptr, 0); - buf_ptr += sizeof(uint32_t); + *buf_ptr++ = 0; // Write BFPT 19th Word // [31, 0]: Octable enable, (8D-8D-8D), 0-8-8 mode (not suported, 0x0) // // Note: Reserved fields of this word should be 0 (JESD216F 6.4.22). - DEV_WRITE(buf_ptr, 0); - buf_ptr += sizeof(uint32_t); + *buf_ptr++ = 0; // Write BFPT 20th Word // [31, 0]: Max (8S-8S-8S) (4D-4D-4D) (4S-4S-4S) speed // (not supported, 0xffffffff) - DEV_WRITE(buf_ptr, UINT32_MAX); - buf_ptr += sizeof(uint32_t); + *buf_ptr++ = UINT32_MAX; // Write BFPT 21st Word // [31, 0]: Fast read support for various modes (not supported, 0x0) // // Note: Reserved fields of this word should be 0 (JESD216F 6.4.24). - DEV_WRITE(buf_ptr, 0); - buf_ptr += sizeof(uint32_t); + *buf_ptr++ = 0; // Write BFPT 22nd Word // [31, 0]: Fast read (1S-1D-1D) (1S-2D-2D) (not supported, 0x0) - DEV_WRITE(buf_ptr, 0); - buf_ptr += sizeof(uint32_t); + *buf_ptr++ = 0; // Write BFPT 23rd Word // [31, 0]: Fast read (1S-4D-4D) (4S-2D-2D) (not supported, 0x0) - DEV_WRITE(buf_ptr, 0); - buf_ptr += sizeof(uint32_t); + *buf_ptr++ = 0; // clang-format on // Fill the remaining space with `0xff`s. - while (buf_ptr < spi_device + SPI_DEVICE_EGRESS_BUFFER_OFFSET + SPI_DEVICE_SFDP_AREA_OFFSET + - SPI_DEVICE_SFDP_AREA_NUM_BYTES) { - DEV_WRITE(buf_ptr, UINT32_MAX); - buf_ptr += sizeof(uint32_t); + while (buf_ptr < buf_end) { + *buf_ptr++ = UINT32_MAX; } } @@ -583,25 +565,20 @@ void spi_device_init(spi_device_t spi_device) spi_device_flash_status_set(spi_device, 0); // Configure commands - spi_device_cmd_info_set(spi_device, SPI_DEVICE_CMD_INFO_0_REG, SPI_DEVICE_OPCODE_READ_STATUS, 0, - 0, false); - spi_device_cmd_info_set(spi_device, SPI_DEVICE_CMD_INFO_3_REG, SPI_DEVICE_OPCODE_READ_JEDEC_ID, - 0, 0, false); - spi_device_cmd_info_set(spi_device, SPI_DEVICE_CMD_INFO_4_REG, SPI_DEVICE_OPCODE_READ_SFDP, + spi_device_cmd_info_set(spi_device, 0, SPI_DEVICE_OPCODE_READ_STATUS, 0, 0, false); + spi_device_cmd_info_set(spi_device, 3, SPI_DEVICE_OPCODE_READ_JEDEC_ID, 0, 0, false); + spi_device_cmd_info_set(spi_device, 4, SPI_DEVICE_OPCODE_READ_SFDP, SPI_DEVICE_CMD_ADDR_MODE_ADDR_3B, 8, false); - spi_device_cmd_info_set(spi_device, SPI_DEVICE_CMD_INFO_5_REG, SPI_DEVICE_OPCODE_READ_DATA, + spi_device_cmd_info_set(spi_device, 5, SPI_DEVICE_OPCODE_READ_DATA, SPI_DEVICE_CMD_ADDR_MODE_ADDR_3B, 0, false); - spi_device_cmd_info_set(spi_device, SPI_DEVICE_CMD_INFO_11_REG, SPI_DEVICE_OPCODE_CHIP_ERASE, 0, - 0, true); - spi_device_cmd_info_set(spi_device, SPI_DEVICE_CMD_INFO_12_REG, SPI_DEVICE_OPCODE_SECTOR_ERASE, + spi_device_cmd_info_set(spi_device, 11, SPI_DEVICE_OPCODE_CHIP_ERASE, 0, 0, true); + spi_device_cmd_info_set(spi_device, 12, SPI_DEVICE_OPCODE_SECTOR_ERASE, SPI_DEVICE_CMD_ADDR_MODE_ADDR_3B, 0, true); - spi_device_cmd_info_set(spi_device, SPI_DEVICE_CMD_INFO_13_REG, SPI_DEVICE_OPCODE_PAGE_PROGRAM, + spi_device_cmd_info_set(spi_device, 13, SPI_DEVICE_OPCODE_PAGE_PROGRAM, SPI_DEVICE_CMD_ADDR_MODE_ADDR_3B, 0, true); - spi_device_cmd_info_set(spi_device, SPI_DEVICE_CMD_INFO_14_REG, SPI_DEVICE_OPCODE_RESET, 0, 0, - true); - spi_device_cmd_info_set(spi_device, SPI_DEVICE_CMD_INFO_15_REG, - SPI_DEVICE_OPCODE_PAGE_PROGRAM4B, SPI_DEVICE_CMD_ADDR_MODE_ADDR_4B, 0, - true); + spi_device_cmd_info_set(spi_device, 14, SPI_DEVICE_OPCODE_RESET, 0, 0, true); + spi_device_cmd_info_set(spi_device, 15, SPI_DEVICE_OPCODE_PAGE_PROGRAM4B, + SPI_DEVICE_CMD_ADDR_MODE_ADDR_4B, 0, true); // Configure WRITE_ENABLE and WRITE_DISABLE commands spi_device_cmd_info_write_enable_set(spi_device, SPI_DEVICE_OPCODE_WRITE_ENABLE); spi_device_cmd_info_write_disable_set(spi_device, SPI_DEVICE_OPCODE_WRITE_DISABLE); @@ -617,43 +594,42 @@ spi_device_cmd_t spi_device_cmd_get_non_blocking(spi_device_t spi_device) .payload_byte_count = 0 }; // Check for software-handled command - if (!spi_device_interrupt_is_pending(spi_device, SPI_DEVICE_INTR_UPLOAD_CMDFIFO_NOT_EMPTY)) { + if (!spi_device_interrupt_any_pending(spi_device, spi_device_intr_upload_cmdfifo_not_empty)) { cmd.status = spi_device_status_empty; return cmd; } // Clear interrupt - spi_device_interrupt_clear(spi_device, SPI_DEVICE_INTR_UPLOAD_CMDFIFO_NOT_EMPTY); + spi_device_interrupt_clear(spi_device, spi_device_intr_upload_cmdfifo_not_empty); // Check for payload overflow - if (spi_device_interrupt_is_pending(spi_device, SPI_DEVICE_INTR_UPLOAD_PAYLOAD_OVERFLOW)) { + if (spi_device_interrupt_any_pending(spi_device, spi_device_intr_upload_payload_overflow)) { cmd.status = spi_device_status_overflow; - spi_device_interrupt_clear(spi_device, SPI_DEVICE_INTR_UPLOAD_PAYLOAD_OVERFLOW); + spi_device_interrupt_clear(spi_device, spi_device_intr_upload_payload_overflow); return cmd; } // Get opcode - cmd.opcode = (uint8_t)spi_device_upload_cmdfifo_read(spi_device); + cmd.opcode = (uint8_t)VOLATILE_READ(spi_device->upload_cmdfifo).data; // Get address - if ((spi_device_upload_status_get(spi_device) & - SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_MASK) != 0) { - cmd.address = spi_device_upload_addrfifo_read(spi_device); + if (VOLATILE_READ(spi_device->upload_status).addrfifo_notempty) { + cmd.address = VOLATILE_READ(spi_device->upload_addrfifo); } else { // No address cmd.address = UINT32_MAX; } // Get payload size - cmd.payload_byte_count = (uint16_t)(spi_device_upload_status2_get(spi_device) & - SPI_DEVICE_UPLOAD_STATUS2_PAYLOAD_DEPTH_MASK); + cmd.payload_byte_count = (uint16_t)VOLATILE_READ(spi_device->upload_status2).payload_depth; return cmd; } spi_device_cmd_t spi_device_cmd_get(spi_device_t spi_device) { // Wait for software-handled command - while (!spi_device_interrupt_is_pending(spi_device, SPI_DEVICE_INTR_UPLOAD_CMDFIFO_NOT_EMPTY)) { + while ( + !spi_device_interrupt_any_pending(spi_device, spi_device_intr_upload_cmdfifo_not_empty)) { } return spi_device_cmd_get_non_blocking(spi_device); diff --git a/sw/device/lib/hal/spi_device.h b/sw/device/lib/hal/spi_device.h index 76e48f975..c6b85a88c 100644 --- a/sw/device/lib/hal/spi_device.h +++ b/sw/device/lib/hal/spi_device.h @@ -4,121 +4,21 @@ #pragma once -#include "hal/mmio.h" +#include "autogen/spi_device.h" #include #include -#define SPI_DEVICE_INTR_STATE_REG (0x0) -#define SPI_DEVICE_INTR_ENABLE_REG (0x4) -#define SPI_DEVICE_INTR_TEST_REG (0x8) -#define SPI_DEVICE_INTR_UPLOAD_CMDFIFO_NOT_EMPTY (0) -#define SPI_DEVICE_INTR_UPLOAD_PAYLOAD_NOT_EMPTY (1) -#define SPI_DEVICE_INTR_UPLOAD_PAYLOAD_OVERFLOW (2) -#define SPI_DEVICE_INTR_READBUF_WATERMARK (3) -#define SPI_DEVICE_INTR_READBUF_FLIP (4) -#define SPI_DEVICE_INTR_TPM_HEADER_NOT_EMPTY (5) -#define SPI_DEVICE_INTR_TPM_RDFIFO_CMD_END (6) -#define SPI_DEVICE_INTR_TPM_RDFIFO_DROP (7) -#define SPI_DEVICE_MAX_INTR (7) - -#define SPI_DEVICE_CTRL_REG (0x10) -#define SPI_DEVICE_CTRL_MODE_OFFSET (4) -#define SPI_DEVICE_CTRL_MODE_MASK (0x1 << 4) - -#define SPI_DEVICE_ADDR_MODE_REG (0x20) -#define SPI_DEVICE_ADDR_MODE_4B_EN_MASK (0x1) -#define SPI_DEVICE_ADDR_MODE_PENDING_MASK (0x70000000) - -#define SPI_DEVICE_FLASH_STATUS_REG (0x28) -#define SPI_DEVICE_FLASH_STATUS_BUSY_MASK (0x1) -#define SPI_DEVICE_FLASH_STATUS_WEL_MASK (0x2) - -#define SPI_DEVICE_JEDEC_CC_REG (0x2C) -#define SPI_DEVICE_JEDEC_CC (0) -#define SPI_DEVICE_JEDEC_NUM_CC (8) - -#define SPI_DEVICE_JEDEC_ID_REG (0x30) -#define SPI_DEVICE_CHIP_REV (0) -#define SPI_DEVICE_CHIP_REV_MASK (0x7) -#define SPI_DEVICE_ROM_BOOTSTRAP (3) -#define SPI_DEVICE_CHIP_GEN (4) -#define SPI_DEVICE_CHIP_GEN_MASK (0xF) -#define SPI_DEVICE_DENSITY (8) -#define SPI_DEVICE_MANUFACTURER_ID (16) - -#define SPI_DEVICE_MAILBOX_ADDR_REG (0x38) - -#define SPI_DEVICE_UPLOAD_STATUS_REG (0x3C) -#define SPI_DEVICE_UPLOAD_STATUS_CMDFIFO_NOTEMPTY_MASK (0x80) -#define SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_MASK (0x8000) - -#define SPI_DEVICE_UPLOAD_STATUS2_REG (0x40) -#define SPI_DEVICE_UPLOAD_STATUS2_PAYLOAD_DEPTH_MASK (0x1FF) - -#define SPI_DEVICE_UPLOAD_CMDFIFO_REG (0x44) -#define SPI_DEVICE_UPLOAD_ADDRFIFO_REG (0x48) - -#define SPI_DEVICE_CMD_FILTER_0_REG (0x4C) -#define SPI_DEVICE_CMD_FILTER_1_REG (0x50) -#define SPI_DEVICE_CMD_FILTER_2_REG (0x54) -#define SPI_DEVICE_CMD_FILTER_3_REG (0x58) -#define SPI_DEVICE_CMD_FILTER_4_REG (0x5C) -#define SPI_DEVICE_CMD_FILTER_5_REG (0x60) -#define SPI_DEVICE_CMD_FILTER_6_REG (0x64) -#define SPI_DEVICE_CMD_FILTER_7_REG (0x68) - -#define SPI_DEVICE_CMD_INFO_0_REG (0x7C) -#define SPI_DEVICE_CMD_INFO_1_REG (0x80) -#define SPI_DEVICE_CMD_INFO_2_REG (0x84) -#define SPI_DEVICE_CMD_INFO_3_REG (0x88) -#define SPI_DEVICE_CMD_INFO_4_REG (0x8C) -#define SPI_DEVICE_CMD_INFO_5_REG (0x90) -#define SPI_DEVICE_CMD_INFO_6_REG (0x94) -#define SPI_DEVICE_CMD_INFO_7_REG (0x98) -#define SPI_DEVICE_CMD_INFO_8_REG (0x9C) -#define SPI_DEVICE_CMD_INFO_9_REG (0xA0) -#define SPI_DEVICE_CMD_INFO_10_REG (0xA4) -#define SPI_DEVICE_CMD_INFO_11_REG (0xA8) -#define SPI_DEVICE_CMD_INFO_12_REG (0xAC) -#define SPI_DEVICE_CMD_INFO_13_REG (0xB0) -#define SPI_DEVICE_CMD_INFO_14_REG (0xB4) -#define SPI_DEVICE_CMD_INFO_15_REG (0xB8) -#define SPI_DEVICE_CMD_INFO_16_REG (0xBC) -#define SPI_DEVICE_CMD_INFO_17_REG (0xC0) -#define SPI_DEVICE_CMD_INFO_18_REG (0xC4) -#define SPI_DEVICE_CMD_INFO_19_REG (0xC8) -#define SPI_DEVICE_CMD_INFO_20_REG (0xCC) -#define SPI_DEVICE_CMD_INFO_21_REG (0xD0) -#define SPI_DEVICE_CMD_INFO_22_REG (0xD4) -#define SPI_DEVICE_CMD_INFO_23_REG (0xD8) -#define SPI_DEVICE_CMD_OPCODE (0) -#define SPI_DEVICE_CMD_ADDR_MODE (8) -#define SPI_DEVICE_CMD_ADDR_MODE_MASK (0x3) -#define SPI_DEVICE_CMD_ADDR_MODE_ADDR_DISABLED (0x0) -#define SPI_DEVICE_CMD_ADDR_MODE_ADDR_CFG (0x1) -#define SPI_DEVICE_CMD_ADDR_MODE_ADDR_3B (0x2) -#define SPI_DEVICE_CMD_ADDR_MODE_ADDR_4B (0x3) -#define SPI_DEVICE_CMD_DUMMY_SIZE (12) -#define SPI_DEVICE_CMD_DUMMY_SIZE_MASK (0x7) -#define SPI_DEVICE_CMD_DUMMY_EN (15) -#define SPI_DEVICE_CMD_UPLOAD (24) -#define SPI_DEVICE_CMD_BUSY (25) -#define SPI_DEVICE_CMD_VALID (31) - -#define SPI_DEVICE_CMD_INFO_EN4B_REG (0xDC) -#define SPI_DEVICE_CMD_INFO_WREN_REG (0xE4) -#define SPI_DEVICE_CMD_INFO_WRDI_REG (0xE8) - -#define SPI_DEVICE_EGRESS_BUFFER_OFFSET (0x1000) -#define SPI_DEVICE_READ_BUFFER_OFFSET (0x0) #define SPI_DEVICE_READ_BUFFER_NUM_BYTES (2048) #define SPI_DEVICE_SFDP_AREA_OFFSET (0xC00) #define SPI_DEVICE_SFDP_AREA_NUM_BYTES (256) -#define SPI_DEVICE_INGRESS_BUFFER_OFFSET (0x1E00) -#define SPI_DEVICE_PAYLOAD_AREA_OFFSET (0x0) #define SPI_DEVICE_PAYLOAD_AREA_NUM_BYTES (256) +#define SPI_DEVICE_CMD_ADDR_MODE_ADDR_DISABLED (0x0) +#define SPI_DEVICE_CMD_ADDR_MODE_ADDR_CFG (0x1) +#define SPI_DEVICE_CMD_ADDR_MODE_ADDR_3B (0x2) +#define SPI_DEVICE_CMD_ADDR_MODE_ADDR_4B (0x3) + #define SPI_DEVICE_SFDP_SIGNATURE (0x50444653) #define SPI_DEVICE_SFDP_MINOR_REVISION (0x0A) #define SPI_DEVICE_SFDP_MAJOR_REVISION (0x01) @@ -155,8 +55,6 @@ #define MOCHA_SPI_DEVICE_DENSITY_BYTES_LOG2 (20) #define MOCHA_SPI_DEVICE_MANUFACTURER_ID (0xef) -typedef void *spi_device_t; - typedef enum spi_device_status { spi_device_status_ready = 0, spi_device_status_empty = 1, @@ -170,53 +68,73 @@ typedef struct spi_device_cmd { uint32_t address; } spi_device_cmd_t; -bool spi_device_interrupt_is_pending(spi_device_t spi_device, uint8_t intr_id); -void spi_device_interrupt_clear(spi_device_t spi_device, uint8_t intr_id); -void spi_device_interrupt_disable_all(spi_device_t spi_device); -void spi_device_interrupt_enable(spi_device_t spi_device, uint8_t intr_id); -void spi_device_interrupt_disable(spi_device_t spi_device, uint8_t intr_id); -void spi_device_interrupt_trigger(spi_device_t spi_device, uint8_t intr_id); +/* interrupts */ +bool spi_device_interrupt_any_pending(spi_device_t spi_device, spi_device_intr intrs); +void spi_device_interrupt_clear(spi_device_t spi_device, spi_device_intr intrs); +void spi_device_interrupt_enable_write(spi_device_t spi_device, spi_device_intr intrs); +void spi_device_interrupt_enable_set(spi_device_t spi_device, spi_device_intr intrs); +void spi_device_interrupt_enable_clear(spi_device_t spi_device, spi_device_intr intrs); +void spi_device_interrupt_force(spi_device_t spi_device, spi_device_intr intrs); + +/* control */ void spi_device_enable_set(spi_device_t spi_device, bool enable); void spi_device_4b_addr_mode_enable_set(spi_device_t spi_device, bool enable); bool spi_device_4b_addr_mode_enable_get(spi_device_t spi_device); + +/* flash status */ void spi_device_flash_status_set(spi_device_t spi_device, uint32_t flash_status); uint32_t spi_device_flash_status_get(spi_device_t spi_device); + +/* JEDEC */ void spi_device_jedec_cc_set(spi_device_t spi_device, uint8_t cc, uint8_t num_cc); uint16_t spi_device_jedec_cc_get(spi_device_t spi_device); void spi_device_jedec_id_set_raw(spi_device_t spi_device, uint32_t data); void spi_device_jedec_id_set(spi_device_t spi_device, bool rom_bootstrap, uint8_t chip_rev, uint8_t chip_gen, uint8_t density, uint8_t manufacturer_id); uint32_t spi_device_jedec_id_get(spi_device_t spi_device); + +/* mailbox */ void spi_device_mailbox_addr_set(spi_device_t spi_device, uint32_t addr); uint32_t spi_device_mailbox_addr_get(spi_device_t spi_device); + +/* upload */ uint32_t spi_device_upload_status_get(spi_device_t spi_device); uint32_t spi_device_upload_status2_get(spi_device_t spi_device); uint32_t spi_device_upload_cmdfifo_read(spi_device_t spi_device); uint32_t spi_device_upload_addrfifo_read(spi_device_t spi_device); -void spi_device_cmd_filter_set(spi_device_t spi_device, uint32_t offset, uint32_t data); -uint32_t spi_device_cmd_filter_get(spi_device_t spi_device, uint32_t offset); -void spi_device_cmd_info_set_raw(spi_device_t spi_device, uint32_t offset, uint32_t data); -void spi_device_cmd_info_set(spi_device_t spi_device, uint32_t offset, uint8_t opcode, + +/* cmd filter - idx is 0-based array index (0..7) */ +void spi_device_cmd_filter_set(spi_device_t spi_device, uint8_t idx, uint32_t data); +uint32_t spi_device_cmd_filter_get(spi_device_t spi_device, uint8_t idx); + +/* cmd info - idx is 0-based array index (0..23) */ +void spi_device_cmd_info_set_raw(spi_device_t spi_device, uint8_t idx, uint32_t data); +void spi_device_cmd_info_set(spi_device_t spi_device, uint8_t idx, uint8_t opcode, uint8_t addr_mode, uint8_t dummy_cycles, bool handled_in_sw); -uint32_t spi_device_cmd_info_get(spi_device_t spi_device, uint32_t offset); +uint32_t spi_device_cmd_info_get(spi_device_t spi_device, uint8_t idx); +void spi_device_cmd_info_4b_enable_set_raw(spi_device_t spi_device, uint32_t data); +void spi_device_cmd_info_4b_enable_set(spi_device_t spi_device, uint8_t opcode); void spi_device_cmd_info_write_enable_set_raw(spi_device_t spi_device, uint32_t data); void spi_device_cmd_info_write_enable_set(spi_device_t spi_device, uint8_t opcode); uint32_t spi_device_cmd_info_write_enable_get(spi_device_t spi_device); void spi_device_cmd_info_write_disable_set_raw(spi_device_t spi_device, uint32_t data); void spi_device_cmd_info_write_disable_set(spi_device_t spi_device, uint8_t opcode); uint32_t spi_device_cmd_info_write_disable_get(spi_device_t spi_device); + +/* buffers */ bool spi_device_flash_read_buffer_write(spi_device_t spi_device, uint32_t offset, uint32_t data); uint32_t spi_device_flash_payload_buffer_read(spi_device_t spi_device, uint32_t offset); static inline uint64_t spi_device_flash_payload_buffer_read64(spi_device_t spi_device, uint32_t offset) { - uintptr_t addr = (uintptr_t)spi_device + SPI_DEVICE_INGRESS_BUFFER_OFFSET + - SPI_DEVICE_PAYLOAD_AREA_OFFSET + offset; - return DEV_READ64(addr); + return *((volatile uint64_t *)&spi_device->ingress_buffer[offset / sizeof(uint32_t)]); } +/* initialisation */ void spi_device_sfdp_table_init(spi_device_t spi_device); void spi_device_init(spi_device_t spi_device); + +/* command receive */ spi_device_cmd_t spi_device_cmd_get(spi_device_t spi_device); spi_device_cmd_t spi_device_cmd_get_non_blocking(spi_device_t spi_device); diff --git a/sw/device/lib/hal/spi_host.c b/sw/device/lib/hal/spi_host.c index 4ca1b8a28..560ad3952 100644 --- a/sw/device/lib/hal/spi_host.c +++ b/sw/device/lib/hal/spi_host.c @@ -25,3 +25,14 @@ uint32_t spi_host_read(spi_host_t spi_host) { return DEV_READ(spi_host + SPI_HOST_RXDATA_REG); } + +uint32_t spi_host_status(spi_host_t spi_host) +{ + return DEV_READ(spi_host + SPI_HOST_STATUS_REG); +} + +void spi_host_wait_for_idle(spi_host_t spi_host) +{ + while ((spi_host_status(spi_host) & SPI_HOST_STATUS_ACTIVE_MASK) != 0) { + }; +} diff --git a/sw/device/lib/hal/spi_host.h b/sw/device/lib/hal/spi_host.h index 5c806e5a0..aed807066 100644 --- a/sw/device/lib/hal/spi_host.h +++ b/sw/device/lib/hal/spi_host.h @@ -15,6 +15,7 @@ #define SPI_HOST_CONTROL_SPIEN_MASK (1u << 31) #define SPI_HOST_CONTROL_OUTPUTEN_MASK (1u << 29) #define SPI_HOST_STATUS_REG (0x14) +#define SPI_HOST_STATUS_ACTIVE_MASK (1u << 30) #define SPI_HOST_CONFIGOPTS_REG (0x18) #define SPI_HOST_CSID_REG (0x1C) #define SPI_HOST_COMMAND_REG (0x20) @@ -32,3 +33,5 @@ typedef void *spi_host_t; void spi_host_init(spi_host_t spi_host); void spi_host_write(spi_host_t spi_host, uint32_t data); uint32_t spi_host_read(spi_host_t spi_host); +uint32_t spi_host_status(spi_host_t spi_host); +void spi_host_wait_for_idle(spi_host_t spi_host); diff --git a/sw/device/lib/hal/uart.c b/sw/device/lib/hal/uart.c index a9895df26..c392bd183 100644 --- a/sw/device/lib/hal/uart.c +++ b/sw/device/lib/hal/uart.c @@ -60,6 +60,16 @@ bool uart_interrupt_any_pending(uart_t uart, uart_intr intrs) return (VOLATILE_READ(uart->intr_state) & intrs) != 0u; } +bool uart_status_any(uart_t uart, uart_status status) +{ + return (VOLATILE_READ(uart->status) & status) != 0u; +} + +bool uart_status_all(uart_t uart, uart_status status) +{ + return (VOLATILE_READ(uart->status) & status) == status; +} + void uart_loopback_set(uart_t uart, bool system_enable, bool line_enable) { uart_ctrl ctrl = VOLATILE_READ(uart->ctrl); diff --git a/sw/device/lib/hal/uart.h b/sw/device/lib/hal/uart.h index b71433110..84fcfa612 100644 --- a/sw/device/lib/hal/uart.h +++ b/sw/device/lib/hal/uart.h @@ -22,6 +22,8 @@ void uart_interrupt_force(uart_t uart, uart_intr intrs); void uart_interrupt_clear(uart_t uart, uart_intr intrs); bool uart_interrupt_all_pending(uart_t uart, uart_intr intrs); bool uart_interrupt_any_pending(uart_t uart, uart_intr intrs); +bool uart_status_any(uart_t uart, uart_status status); +bool uart_status_all(uart_t uart, uart_status status); void uart_loopback_set(uart_t uart, bool system_enable, bool line_enable); char uart_in(uart_t uart); diff --git a/sw/device/lib/test_framework/main.c b/sw/device/lib/test_framework/main.c index b7167b2d5..0a8b4f6de 100644 --- a/sw/device/lib/test_framework/main.c +++ b/sw/device/lib/test_framework/main.c @@ -78,9 +78,15 @@ test_exception_handler(struct trap_registers *registers, struct trap_context *co void *dv_test_status = mocha_system_dv_test_status(); uart_init(console); + //Flush the uart + while (!uart_status_any(console, uart_status_txidle)) { + }; DEV_WRITE(dv_test_status, TEST_STATUS_IN_TEST); bool result = test_main(console); + //Flush the uart + while (!uart_status_any(console, uart_status_txidle)) { + }; test_exit(result); } diff --git a/sw/device/tests/axi_sram/smoketest.c b/sw/device/tests/axi_sram/smoketest.c index cac2698f0..fc3b04bf8 100644 --- a/sw/device/tests/axi_sram/smoketest.c +++ b/sw/device/tests/axi_sram/smoketest.c @@ -5,7 +5,7 @@ #include #include -bool rapid_write_test() +static bool rapid_write_test() { uint64_t d1 = 0xB03747F359ABBCFEUL, res1; uint64_t d2 = 0x0A197F0071E028A1UL, res2; diff --git a/sw/device/tests/spi_device/smoketest.c b/sw/device/tests/spi_device/smoketest.c index a4b81cf09..752928d9e 100644 --- a/sw/device/tests/spi_device/smoketest.c +++ b/sw/device/tests/spi_device/smoketest.c @@ -13,32 +13,32 @@ enum { mip_read_retry_count = 20u, }; -bool cmd_filter_readback_test(spi_device_t spi_device, uint32_t offset) +bool cmd_filter_readback_test(spi_device_t spi_device, uint8_t idx) { - spi_device_cmd_filter_set(spi_device, offset, 0x55555555); - if (spi_device_cmd_filter_get(spi_device, offset) != 0x55555555) { + spi_device_cmd_filter_set(spi_device, idx, 0x55555555); + if (spi_device_cmd_filter_get(spi_device, idx) != 0x55555555) { return false; } - spi_device_cmd_filter_set(spi_device, offset, 0xAAAAAAAA); - if (spi_device_cmd_filter_get(spi_device, offset) != 0xAAAAAAAA) { + spi_device_cmd_filter_set(spi_device, idx, 0xAAAAAAAA); + if (spi_device_cmd_filter_get(spi_device, idx) != 0xAAAAAAAA) { return false; } return true; } -bool cmd_info_readback_test(spi_device_t spi_device, uint32_t offset) +bool cmd_info_readback_test(spi_device_t spi_device, uint8_t idx) { const uint32_t CMD_INFO_RESET_MASK = 0x83FFFFFF; - spi_device_cmd_info_set_raw(spi_device, offset, 0xAAAAAAAA & CMD_INFO_RESET_MASK); - if ((spi_device_cmd_info_get(spi_device, offset) & CMD_INFO_RESET_MASK) != + spi_device_cmd_info_set_raw(spi_device, idx, 0xAAAAAAAA & CMD_INFO_RESET_MASK); + if ((spi_device_cmd_info_get(spi_device, idx) & CMD_INFO_RESET_MASK) != (0xAAAAAAAA & CMD_INFO_RESET_MASK)) { return false; } - spi_device_cmd_info_set_raw(spi_device, offset, 0x55555555 & CMD_INFO_RESET_MASK); - if ((spi_device_cmd_info_get(spi_device, offset) & CMD_INFO_RESET_MASK) != + spi_device_cmd_info_set_raw(spi_device, idx, 0x55555555 & CMD_INFO_RESET_MASK); + if ((spi_device_cmd_info_get(spi_device, idx) & CMD_INFO_RESET_MASK) != (0x55555555 & CMD_INFO_RESET_MASK)) { return false; } @@ -83,25 +83,17 @@ bool reg_test(spi_device_t spi_device) return false; } - if (!(cmd_filter_readback_test(spi_device, SPI_DEVICE_CMD_FILTER_0_REG) && - cmd_filter_readback_test(spi_device, SPI_DEVICE_CMD_FILTER_1_REG) && - cmd_filter_readback_test(spi_device, SPI_DEVICE_CMD_FILTER_2_REG) && - cmd_filter_readback_test(spi_device, SPI_DEVICE_CMD_FILTER_3_REG) && - cmd_filter_readback_test(spi_device, SPI_DEVICE_CMD_FILTER_4_REG) && - cmd_filter_readback_test(spi_device, SPI_DEVICE_CMD_FILTER_5_REG) && - cmd_filter_readback_test(spi_device, SPI_DEVICE_CMD_FILTER_6_REG) && - cmd_filter_readback_test(spi_device, SPI_DEVICE_CMD_FILTER_7_REG))) { + if (!(cmd_filter_readback_test(spi_device, 0) && cmd_filter_readback_test(spi_device, 1) && + cmd_filter_readback_test(spi_device, 2) && cmd_filter_readback_test(spi_device, 3) && + cmd_filter_readback_test(spi_device, 4) && cmd_filter_readback_test(spi_device, 5) && + cmd_filter_readback_test(spi_device, 6) && cmd_filter_readback_test(spi_device, 7))) { return false; } - if (!(cmd_info_readback_test(spi_device, SPI_DEVICE_CMD_INFO_0_REG) && - cmd_info_readback_test(spi_device, SPI_DEVICE_CMD_INFO_1_REG) && - cmd_info_readback_test(spi_device, SPI_DEVICE_CMD_INFO_2_REG) && - cmd_info_readback_test(spi_device, SPI_DEVICE_CMD_INFO_3_REG) && - cmd_info_readback_test(spi_device, SPI_DEVICE_CMD_INFO_20_REG) && - cmd_info_readback_test(spi_device, SPI_DEVICE_CMD_INFO_21_REG) && - cmd_info_readback_test(spi_device, SPI_DEVICE_CMD_INFO_22_REG) && - cmd_info_readback_test(spi_device, SPI_DEVICE_CMD_INFO_23_REG))) { + if (!(cmd_info_readback_test(spi_device, 0) && cmd_info_readback_test(spi_device, 1) && + cmd_info_readback_test(spi_device, 2) && cmd_info_readback_test(spi_device, 3) && + cmd_info_readback_test(spi_device, 20) && cmd_info_readback_test(spi_device, 21) && + cmd_info_readback_test(spi_device, 22) && cmd_info_readback_test(spi_device, 23))) { return false; } @@ -116,8 +108,8 @@ bool machine_irq_test(spi_device_t spi_device, plic_t plic) plic_interrupt_priority_write(plic, mocha_system_irq_spi_device, 3); plic_machine_priority_threshold_write(plic, 0); - spi_device_interrupt_disable_all(spi_device); - spi_device_interrupt_enable(spi_device, SPI_DEVICE_INTR_UPLOAD_PAYLOAD_OVERFLOW); + spi_device_interrupt_enable_write(spi_device, spi_device_intr_none); + spi_device_interrupt_enable_set(spi_device, spi_device_intr_upload_payload_overflow); plic_machine_interrupt_enable_set(plic, mocha_system_irq_spi_device); @@ -126,7 +118,7 @@ bool machine_irq_test(spi_device_t spi_device, plic_t plic) return false; } - spi_device_interrupt_trigger(spi_device, SPI_DEVICE_INTR_UPLOAD_PAYLOAD_OVERFLOW); + spi_device_interrupt_force(spi_device, spi_device_intr_upload_payload_overflow); // Check that mip MEIP is set following the triggered interrupt for (size_t i = 0; i < mip_read_retry_count; i++) { @@ -140,7 +132,7 @@ bool machine_irq_test(spi_device_t spi_device, plic_t plic) } intr_id = plic_machine_interrupt_claim(plic); - spi_device_interrupt_clear(spi_device, SPI_DEVICE_INTR_UPLOAD_PAYLOAD_OVERFLOW); + spi_device_interrupt_clear(spi_device, spi_device_intr_upload_payload_overflow); plic_machine_interrupt_complete(plic, intr_id); // Check that mip MEIP is clear @@ -159,8 +151,8 @@ bool supervisor_irq_test(spi_device_t spi_device, plic_t plic) plic_interrupt_priority_write(plic, mocha_system_irq_spi_device, 3); plic_supervisor_priority_threshold_write(plic, 0); - spi_device_interrupt_disable_all(spi_device); - spi_device_interrupt_enable(spi_device, SPI_DEVICE_INTR_READBUF_FLIP); + spi_device_interrupt_enable_write(spi_device, spi_device_intr_none); + spi_device_interrupt_enable_set(spi_device, spi_device_intr_readbuf_flip); plic_supervisor_interrupt_enable_set(plic, mocha_system_irq_spi_device); @@ -169,7 +161,7 @@ bool supervisor_irq_test(spi_device_t spi_device, plic_t plic) return false; } - spi_device_interrupt_trigger(spi_device, SPI_DEVICE_INTR_READBUF_FLIP); + spi_device_interrupt_force(spi_device, spi_device_intr_readbuf_flip); // Check that mip SEIP is set following the triggered interrupt for (size_t i = 0; i < mip_read_retry_count; i++) { @@ -183,7 +175,7 @@ bool supervisor_irq_test(spi_device_t spi_device, plic_t plic) } intr_id = plic_supervisor_interrupt_claim(plic); - spi_device_interrupt_clear(spi_device, SPI_DEVICE_INTR_READBUF_FLIP); + spi_device_interrupt_clear(spi_device, spi_device_intr_readbuf_flip); plic_supervisor_interrupt_complete(plic, intr_id); // Check that mip SEIP is clear diff --git a/sw/device/tests/spi_host/smoketest.c b/sw/device/tests/spi_host/smoketest.c index 658f22cdf..46ef6b0c2 100644 --- a/sw/device/tests/spi_host/smoketest.c +++ b/sw/device/tests/spi_host/smoketest.c @@ -16,6 +16,7 @@ bool test_main() spi_host = mocha_system_spi_host(); spi_host_init(spi_host); spi_host_write(spi_host, tx_data); + spi_host_wait_for_idle(spi_host); rx_data = spi_host_read(spi_host); return tx_data == rx_data; } diff --git a/sw/device/tests/uart/smoketest.c b/sw/device/tests/uart/smoketest.c index b05b2cf18..241ad3b8a 100644 --- a/sw/device/tests/uart/smoketest.c +++ b/sw/device/tests/uart/smoketest.c @@ -3,26 +3,38 @@ // SPDX-License-Identifier: Apache-2.0 #include "hal/uart.h" +#include "runtime/print.h" #include #include -const char uart_loopback_test_string[] = "Test String"; +const static char uart_loopback_test_string[] = "Test String"; static bool loopback_test(uart_t uart) { + // Flush the uart + while (!uart_status_any(uart, uart_status_txidle)) { + }; + uart_loopback_set(uart, true, true); for (uint32_t idx = 0; idx < sizeof(uart_loopback_test_string); idx++) { uart_out(uart, uart_loopback_test_string[idx]); } + // Wait for the transmission to finish + while (!uart_status_any(uart, uart_status_txidle)) { + }; + uart_loopback_set(uart, false, false); bool res = true; for (uint32_t idx = 0; idx < sizeof(uart_loopback_test_string); idx++) { - if (uart_in(uart) != uart_loopback_test_string[idx]) { + while (uart_status_any(uart, uart_status_rxempty)) { + }; + char rx = uart_in(uart); + if (rx != uart_loopback_test_string[idx]) { + uprintf(uart, "Expected: %c, got: %c\n", rx, uart_loopback_test_string[idx]); res = false; break; } } - uart_loopback_set(uart, false, false); return res; } diff --git a/util/rdlgenerator.py b/util/rdlgenerator.py index cb9ac8249..1a197ed98 100755 --- a/util/rdlgenerator.py +++ b/util/rdlgenerator.py @@ -269,7 +269,7 @@ def emit_register_flag_enum(device_name: str, reg: dict) -> str: """ reg_name = reg["name"].lower() fully_qualified_type_name = "_".join([device_name, reg_name]) - enum_variants = [] + enum_variants = [f"{fully_qualified_type_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]) @@ -288,7 +288,7 @@ def emit_common_device_register_declaration( ) -> tuple[str, str]: 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 = [f"{fully_qualified_type_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])