From 8549e5b5b38b7da4e45581f0d8c3c862d7503d1e Mon Sep 17 00:00:00 2001 From: Alexander Williams Date: Wed, 3 Jan 2024 13:34:55 -0800 Subject: [PATCH] SQUASHME: spi_device: Remove generic mode TLTs Signed-off-by: Alexander Williams --- .../data/ip/chip_spi_device_testplan.hjson | 35 -- hw/top_earlgrey/dv/chip_sim_cfg.hjson | 8 +- hw/top_earlgrey/dv/env/chip_env.core | 1 - .../seq_lib/chip_sw_spi_device_tx_rx_vseq.sv | 79 ---- .../dv/env/seq_lib/chip_vseq_list.sv | 1 - sw/device/tests/sim_dv/BUILD | 19 - .../tests/sim_dv/spi_device_tpm_tx_rx_test.c | 8 +- sw/device/tests/sim_dv/spi_passthrough_test.c | 6 +- sw/device/tests/sim_dv/spi_tx_rx_test.c | 370 ------------------ sw/device/tests/sival/BUILD | 1 - .../tests/chip/spi_device_ottf_console/BUILD | 22 -- .../chip/spi_device_ottf_console/src/main.rs | 75 ---- sw/host/tests/chip/spi_device_smoketest/BUILD | 23 -- .../chip/spi_device_smoketest/src/main.rs | 143 ------- 14 files changed, 6 insertions(+), 785 deletions(-) delete mode 100644 hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tx_rx_vseq.sv delete mode 100644 sw/device/tests/sim_dv/spi_tx_rx_test.c delete mode 100644 sw/host/tests/chip/spi_device_ottf_console/BUILD delete mode 100644 sw/host/tests/chip/spi_device_ottf_console/src/main.rs delete mode 100644 sw/host/tests/chip/spi_device_smoketest/BUILD delete mode 100644 sw/host/tests/chip/spi_device_smoketest/src/main.rs diff --git a/hw/top_earlgrey/data/ip/chip_spi_device_testplan.hjson b/hw/top_earlgrey/data/ip/chip_spi_device_testplan.hjson index 4881d76445c98b..11aa53cc5c7281 100644 --- a/hw/top_earlgrey/data/ip/chip_spi_device_testplan.hjson +++ b/hw/top_earlgrey/data/ip/chip_spi_device_testplan.hjson @@ -6,41 +6,6 @@ name: chip_spi_device testpoints: [ // SPI_DEVICE (pre-verified IP) integration tests: - { - name: chip_sw_spi_device_tx_rx - desc: '''Verify the transmission of data on the chip's SPI device port in generic mode. - - - The testbench sends a known payload over the chip's SPI device input port. - - At the same time, the SW test sends a known payload out over the chip's SPI device - output port. - - On reception, both payloads are checked for integrity. - - SW validates the reception of the following interrupts: - - RX fifo full - - RX fifo over level - - TX fifo under level - - RX overflow - - TX underflow - - Run with min (6MHz), typical (24Mhz) and max(30MHz) SPI clk frequencies. - - Ensure that the spi_device does not receive transactions when the csb is high. - ''' - stage: V2 - // Can function as a smoketest, but also may be useful as part of a bootloader for early bring-up. - si_stage: SV2 - lc_states: [ - "TEST_UNLOCKED", - "DEV", - "PROD", - "PROD_END", - "RMA", - ] - features: [ - "SPI_DEVICE.MODE.GENERIC", - "SPI_DEVICE.MODE.GENERIC.ASYNC_FIFOS", - "SPI_DEVICE.MODE.GENERIC.DPSRAM_TXF_RXF", - ] - tests: ["chip_sw_spi_device_tx_rx"] - bazel: ["//sw/device/tests:spi_device_smoketest"] - } { name: chip_sw_spi_device_flash_mode desc: '''Verify the SPI device in flash mode. diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson index c764f16ab697f7..a5cc2d9a0f90a5 100644 --- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson +++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson @@ -685,12 +685,6 @@ sw_images: ["//sw/device/tests/sim_dv:i2c_device_tx_rx_test:1:new_rules"] en_run_modes: ["sw_test_mode_test_rom"] } - { - name: chip_sw_spi_device_tx_rx - uvm_test_seq: chip_sw_spi_device_tx_rx_vseq - sw_images: ["//sw/device/tests/sim_dv:spi_tx_rx_test:1:new_rules"] - en_run_modes: ["sw_test_mode_test_rom"] - } { name: chip_sw_spi_device_tpm uvm_test_seq: chip_sw_spi_device_tpm_vseq @@ -2159,7 +2153,7 @@ name: xcelium_ci_1 tests: ["chip_sw_rv_core_ibex_address_translation", "chip_sw_rv_timer_irq", - "chip_sw_spi_device_tx_rx", + "chip_sw_spi_device_tpm", "chip_sw_usb_ast_clk_calib", "chip_sw_plic_sw_irq", "chip_sw_aes_enc", diff --git a/hw/top_earlgrey/dv/env/chip_env.core b/hw/top_earlgrey/dv/env/chip_env.core index b7cf1059cbd300..ddab67579dd374 100644 --- a/hw/top_earlgrey/dv/env/chip_env.core +++ b/hw/top_earlgrey/dv/env/chip_env.core @@ -100,7 +100,6 @@ filesets: - seq_lib/chip_sw_lc_ctrl_program_error_vseq.sv: {is_include_file: true} - seq_lib/chip_sw_otp_ctrl_vendor_test_csr_access_vseq.sv: {is_include_file: true} - seq_lib/chip_sw_otp_ctrl_escalation_vseq.sv: {is_include_file: true} - - seq_lib/chip_sw_spi_device_tx_rx_vseq.sv: {is_include_file: true} - seq_lib/chip_sw_spi_host_tx_rx_vseq.sv: {is_include_file: true} - seq_lib/chip_sw_spi_passthrough_collision_vseq.sv: {is_include_file: true} - seq_lib/chip_sw_spi_passthrough_vseq.sv: {is_include_file: true} diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tx_rx_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tx_rx_vseq.sv deleted file mode 100644 index 4f749c68707a15..00000000000000 --- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tx_rx_vseq.sv +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class chip_sw_spi_device_tx_rx_vseq extends chip_sw_base_vseq; - `uvm_object_utils(chip_sw_spi_device_tx_rx_vseq) - - `uvm_object_new - - localparam uint SPI_DEVICE_DATA_SIZE = 128; - localparam uint SPI_DEVICE_RX_SRAM_SIZE = 1024; - - // A set of bytes to be send from SPI_HOST to SPI_DEVICE RX FIFO. - rand bit [7:0] spi_device_rx_data[]; - constraint spi_device_rx_data_c { - spi_device_rx_data.size() == SPI_DEVICE_DATA_SIZE; - } - - // A set of bytes expected to be received on SPI_HOST from SPI_DEVICE TX FIFO. - rand bit [7:0] exp_spi_device_tx_data[]; - constraint exp_spi_device_tx_data_c { - exp_spi_device_tx_data.size() == SPI_DEVICE_DATA_SIZE; - } - - virtual task sync_with_sw(); - `DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInWfi) - `DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInTest) - endtask:sync_with_sw - - virtual task cpu_init(); - super.cpu_init(); - sw_symbol_backdoor_overwrite("spi_device_tx_data", exp_spi_device_tx_data); - sw_symbol_backdoor_overwrite("exp_spi_device_rx_data", spi_device_rx_data); - endtask - - virtual task body(); - bit [7:0] spi_device_tx_data[$]; - super.body(); - - // Wait SPI_DEVICE filled TX FIFO, otherwise SDO will be X - sync_with_sw(); - csr_spinwait(.ptr(ral.spi_device.status.txf_full), .exp_data('b1), .backdoor(1), - .spinwait_delay_ns(1)); - - // Send SPI_HOST data to SPI_DEVICE RX_FIFO and get tx_data from SPI_DEVICE TX_FIFO - // Check if received tx_data against expected value - send_spi_host_rx_data(spi_device_tx_data, SPI_DEVICE_DATA_SIZE); - foreach (spi_device_tx_data[i]) begin - `DV_CHECK_CASE_EQ(spi_device_tx_data[i], exp_spi_device_tx_data[i]) - end - - // Wait for the CPU to read out the RX_FIFO - sync_with_sw(); - - // Send data to fill RX_SRAM to test RX SRAM FIFO full interrupt - send_spi_host_rx_data(spi_device_tx_data, SPI_DEVICE_RX_SRAM_SIZE); - - // Wait for RX_FULL interrupt to fire - sync_with_sw(); - - // Send an extra data to test RX Async FIFO overflow - send_spi_host_rx_data(spi_device_tx_data, SPI_DEVICE_DATA_SIZE); - endtask - - virtual task send_spi_host_rx_data(ref bit [7:0] device_data[$],input int size); - spi_host_seq m_spi_host_seq; - `uvm_create_on(m_spi_host_seq, p_sequencer.spi_host_sequencer_h) - if (size == SPI_DEVICE_DATA_SIZE) begin - `DV_CHECK_RANDOMIZE_WITH_FATAL(m_spi_host_seq, - data.size() == size; - foreach (data[i]) {data[i] == spi_device_rx_data[i];}) - end else begin - `DV_CHECK_RANDOMIZE_WITH_FATAL(m_spi_host_seq, data.size() == size;) - end - `uvm_send(m_spi_host_seq) - device_data = m_spi_host_seq.rsp.data; - endtask - -endclass : chip_sw_spi_device_tx_rx_vseq diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv index 0a6755aa92f797..725156abc27e16 100644 --- a/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv +++ b/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv @@ -47,7 +47,6 @@ `include "chip_sw_lc_walkthrough_testunlocks_vseq.sv" `include "chip_sw_otp_ctrl_vendor_test_csr_access_vseq.sv" `include "chip_sw_otp_ctrl_escalation_vseq.sv" -`include "chip_sw_spi_device_tx_rx_vseq.sv" `include "chip_sw_spi_host_tx_rx_vseq.sv" `include "chip_sw_spi_passthrough_vseq.sv" `include "chip_sw_spi_passthrough_collision_vseq.sv" diff --git a/sw/device/tests/sim_dv/BUILD b/sw/device/tests/sim_dv/BUILD index 0b0f5c2a213b5d..3280de3e19deee 100644 --- a/sw/device/tests/sim_dv/BUILD +++ b/sw/device/tests/sim_dv/BUILD @@ -652,25 +652,6 @@ opentitan_test( ], ) -opentitan_test( - name = "spi_tx_rx_test", - srcs = ["spi_tx_rx_test.c"], - exec_env = {"//hw/top_earlgrey:sim_dv": None}, - deps = [ - "//hw/top_earlgrey/sw/autogen:top_earlgrey", - "//sw/device/lib/arch:device", - "//sw/device/lib/base:mmio", - "//sw/device/lib/dif:base", - "//sw/device/lib/dif:rv_plic", - "//sw/device/lib/dif:spi_device", - "//sw/device/lib/runtime:hart", - "//sw/device/lib/runtime:irq", - "//sw/device/lib/runtime:log", - "//sw/device/lib/testing/test_framework:ottf_main", - "//sw/device/lib/testing/test_framework:status", - ], -) - opentitan_test( name = "spi_device_tpm_tx_rx_test", srcs = ["spi_device_tpm_tx_rx_test.c"], diff --git a/sw/device/tests/sim_dv/spi_device_tpm_tx_rx_test.c b/sw/device/tests/sim_dv/spi_device_tpm_tx_rx_test.c index 68e91edf9ebb16..63d670d2d3a9cf 100644 --- a/sw/device/tests/sim_dv/spi_device_tpm_tx_rx_test.c +++ b/sw/device/tests/sim_dv/spi_device_tpm_tx_rx_test.c @@ -69,12 +69,6 @@ static void en_plic_irqs(dif_rv_plic_t *plic) { static void en_spi_device_irqs(dif_spi_device_t *spi_device) { dif_spi_device_irq_t spi_device_irqs[] = { - kDifSpiDeviceIrqGenericRxFull, - kDifSpiDeviceIrqGenericRxWatermark, - kDifSpiDeviceIrqGenericTxWatermark, - kDifSpiDeviceIrqGenericRxError, - kDifSpiDeviceIrqGenericRxOverflow, - kDifSpiDeviceIrqGenericTxUnderflow, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, kDifSpiDeviceIrqUploadPayloadNotEmpty, kDifSpiDeviceIrqUploadPayloadOverflow, @@ -96,7 +90,7 @@ void ottf_external_isr(uint32_t *exc_info) { spi_device_isr_ctx_t spi_device_ctx = { .spi_device = &spi_device.dev, .plic_spi_device_start_irq_id = - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull, + kTopEarlgreyPlicIrqIdSpiDeviceUploadCmdfifoNotEmpty, .expected_irq = kDifSpiDeviceIrqTpmHeaderNotEmpty, .is_only_irq = true}; diff --git a/sw/device/tests/sim_dv/spi_passthrough_test.c b/sw/device/tests/sim_dv/spi_passthrough_test.c index 6a81a69bd473e9..1768f8ea1dc0b4 100644 --- a/sw/device/tests/sim_dv/spi_passthrough_test.c +++ b/sw/device/tests/sim_dv/spi_passthrough_test.c @@ -402,8 +402,10 @@ bool test_main(void) { // Enable all spi_device and spi_host interrupts, and check that they do not // trigger unless command upload is enabled. dif_spi_device_irq_t all_spi_device_irqs[] = { - kDifSpiDeviceIrqUploadCmdfifoNotEmpty, kDifSpiDeviceIrqReadbufWatermark, - kDifSpiDeviceIrqReadbufFlip, kDifSpiDeviceIrqTpmHeaderNotEmpty, + kDifSpiDeviceIrqUploadCmdfifoNotEmpty, + kDifSpiDeviceIrqReadbufWatermark, + kDifSpiDeviceIrqReadbufFlip, + kDifSpiDeviceIrqTpmHeaderNotEmpty, }; for (int i = 0; i < ARRAYSIZE(all_spi_device_irqs); ++i) { dif_spi_device_irq_t irq = all_spi_device_irqs[i]; diff --git a/sw/device/tests/sim_dv/spi_tx_rx_test.c b/sw/device/tests/sim_dv/spi_tx_rx_test.c deleted file mode 100644 index 96d8337a8c005b..00000000000000 --- a/sw/device/tests/sim_dv/spi_tx_rx_test.c +++ /dev/null @@ -1,370 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -#include "sw/device/lib/arch/device.h" -#include "sw/device/lib/base/mmio.h" -#include "sw/device/lib/dif/dif_rv_plic.h" -#include "sw/device/lib/dif/dif_spi_device.h" -#include "sw/device/lib/runtime/hart.h" -#include "sw/device/lib/runtime/ibex.h" -#include "sw/device/lib/runtime/irq.h" -#include "sw/device/lib/runtime/log.h" -#include "sw/device/lib/testing/test_framework/check.h" -#include "sw/device/lib/testing/test_framework/ottf_main.h" -#include "sw/device/lib/testing/test_framework/status.h" - -#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" - -#define SPI_DEVICE_DATASET_SIZE 128 -#define SPI_DEVICE_NUM_IRQS 6 - -static const uint16_t kFifoLen = 0x400; -static dif_rv_plic_t plic0; -static dif_spi_device_handle_t spi_device; - -// A set of bytes to be send out by spi_device. -// This array will be override with random values in UVM sequence. -static const uint8_t spi_device_tx_data[SPI_DEVICE_DATASET_SIZE] = { - 0xe8, 0x50, 0xc6, 0xb4, 0xbe, 0x16, 0xed, 0x55, 0x16, 0x1d, 0xe6, 0x1c, - 0xde, 0x9f, 0xfd, 0x24, 0x89, 0x81, 0x4d, 0x0d, 0x1a, 0x12, 0x4f, 0x57, - 0xea, 0xd6, 0x6f, 0xc0, 0x7d, 0x46, 0xe7, 0x37, 0x81, 0xd3, 0x8e, 0x16, - 0xad, 0x7b, 0xd0, 0xe2, 0x4f, 0xff, 0x39, 0xe6, 0x71, 0x3c, 0x82, 0x04, - 0xec, 0x3a, 0x27, 0xcc, 0x3d, 0x58, 0x0e, 0x56, 0xd2, 0xd2, 0xb9, 0xa3, - 0xb5, 0x3d, 0xc0, 0x40, 0xba, 0x90, 0x16, 0xd8, 0xe3, 0xa4, 0x22, 0x74, - 0x80, 0xcb, 0x7b, 0xde, 0xd7, 0x3f, 0x4d, 0x93, 0x4d, 0x59, 0x79, 0x88, - 0x24, 0xe7, 0x68, 0x8b, 0x7a, 0x78, 0xb7, 0x07, 0x09, 0x26, 0xcf, 0x6b, - 0x52, 0xd9, 0x4c, 0xd3, 0x33, 0xdf, 0x2e, 0x0d, 0x3b, 0xab, 0x45, 0x85, - 0xc2, 0xc2, 0x19, 0xe5, 0xc7, 0x2b, 0xb0, 0xf6, 0xcb, 0x06, 0xf6, 0xe2, - 0xf5, 0xb1, 0xab, 0xef, 0x6f, 0xd8, 0x23, 0xfd, -}; - -// The set of bytes expected to be received by spi_device from spi_host. -// This array will be override with random values in UVM sequence. -static const uint8_t exp_spi_device_rx_data[SPI_DEVICE_DATASET_SIZE] = { - 0x1b, 0x95, 0xc5, 0xb5, 0x8a, 0xa4, 0xa8, 0x9f, 0x6a, 0x7d, 0x6b, 0x0c, - 0xcd, 0xd5, 0xa6, 0x8f, 0x07, 0x3a, 0x9e, 0x82, 0xe6, 0xa2, 0x2b, 0xe0, - 0x0c, 0x30, 0xe8, 0x5a, 0x05, 0x14, 0x79, 0x8a, 0xFf, 0x88, 0x29, 0xda, - 0xc8, 0xdd, 0x82, 0xd5, 0x68, 0xa5, 0x9d, 0x5a, 0x48, 0x02, 0x7f, 0x24, - 0x32, 0xaf, 0x9d, 0xca, 0xa7, 0x06, 0x0c, 0x96, 0x65, 0x18, 0xe4, 0x7f, - 0x26, 0x44, 0xf3, 0x14, 0xC1, 0xe7, 0xd9, 0x82, 0xf7, 0x64, 0xe8, 0x68, - 0xf9, 0x6c, 0xa9, 0xe7, 0xd1, 0x9b, 0xac, 0xe1, 0xFd, 0xd8, 0x59, 0xb7, - 0x8e, 0xdc, 0x24, 0xb8, 0xa7, 0xaf, 0x20, 0xee, 0x6c, 0x61, 0x48, 0x41, - 0xB4, 0x62, 0x3c, 0xcb, 0x2c, 0xbb, 0xe4, 0x44, 0x97, 0x8a, 0x5e, 0x2f, - 0x7f, 0x2b, 0x10, 0xcc, 0x7d, 0x89, 0x32, 0xfd, 0xfd, 0x58, 0x7f, 0xd8, - 0xc7, 0x33, 0xd1, 0x6a, 0xc7, 0xba, 0x78, 0x69, -}; - -// Set our expectation & event indications of the interrupts we intend to -// exercise in this test. These are declared volatile since they are used by the -// ISR. -static volatile bool expected_irqs[SPI_DEVICE_NUM_IRQS]; -static volatile bool fired_irqs[SPI_DEVICE_NUM_IRQS]; - -/** - * Provides external irq handling for this test. - * - * This function overrides the default OTTF external ISR. - */ -void ottf_external_isr(uint32_t *exc_info) { - // Find which interrupt fired at PLIC by claiming it. - dif_rv_plic_irq_id_t plic_irq_id; - CHECK_DIF_OK( - dif_rv_plic_irq_claim(&plic0, kTopEarlgreyPlicTargetIbex0, &plic_irq_id)); - - // Check if it is the right peripheral. - top_earlgrey_plic_peripheral_t peripheral = (top_earlgrey_plic_peripheral_t) - top_earlgrey_plic_interrupt_for_peripheral[plic_irq_id]; - CHECK(peripheral == kTopEarlgreyPlicPeripheralSpiDevice, - "Interurpt from unexpected peripheral: %d", peripheral); - - // Correlate the interrupt fired at PLIC with SPI DEVICE. - dif_spi_device_irq_t spi_device_irq = 0; - switch (plic_irq_id) { - case kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull: - spi_device_irq = kDifSpiDeviceIrqGenericRxFull; - CHECK(expected_irqs[spi_device_irq], "Unexpected RX full interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark: - spi_device_irq = kDifSpiDeviceIrqGenericRxWatermark; - CHECK(expected_irqs[spi_device_irq], - "Unexpected RX above level interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark: - spi_device_irq = kDifSpiDeviceIrqGenericTxWatermark; - CHECK(expected_irqs[spi_device_irq], - "Unexpected TX below level interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError: - spi_device_irq = kDifSpiDeviceIrqGenericRxError; - CHECK(expected_irqs[spi_device_irq], "Unexpected RX error interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow: - spi_device_irq = kDifSpiDeviceIrqGenericRxOverflow; - CHECK(expected_irqs[spi_device_irq], "Unexpected RX overflow interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow: - spi_device_irq = kDifSpiDeviceIrqGenericTxUnderflow; - CHECK(expected_irqs[spi_device_irq], "Unexpected TX underflow interrupt"); - // TxUnderflow keeps firing as TX fifo is empty but TB controls host to - // keep sending data and requesting data from device, so disable this - // interrupt once fired. Since TxUnderflow keeps firing, PC can not go - // back to the main program, disable the interrupt here instead of in the - // main program. - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device.dev, kDifSpiDeviceIrqGenericTxUnderflow, - kDifToggleDisabled)); - break; - default: - LOG_ERROR("Unexpected interrupt (at PLIC): %d", plic_irq_id); - test_status_set(kTestStatusFailed); - } - fired_irqs[spi_device_irq] = true; - LOG_INFO("%s: %d", __func__, spi_device_irq); - - // Check if the same interrupt fired at SPI DEVICE as well. - bool flag_out; - CHECK_DIF_OK(dif_spi_device_irq_is_pending(&spi_device.dev, spi_device_irq, - &flag_out)); - CHECK(flag_out, - "SPI_DEVICE interrupt fired at PLIC did not fire at SPI_DEVICE"); - - // Clear the interrupt at SPI DEVICE. - CHECK_DIF_OK(dif_spi_device_irq_acknowledge(&spi_device.dev, spi_device_irq)); - - // Complete the IRQ at PLIC. - CHECK_DIF_OK(dif_rv_plic_irq_complete(&plic0, kTopEarlgreyPlicTargetIbex0, - plic_irq_id)); -} - -/** - * Initializes SPI_DEVICE and enables the relevant interrupts. - */ -static void spi_device_init_with_irqs( - mmio_region_t base_addr, dif_spi_device_handle_t *spi_device, - dif_spi_device_config_t spi_device_config) { - LOG_INFO("Initializing the SPI_DEVICE."); - CHECK_DIF_OK(dif_spi_device_init_handle(base_addr, spi_device)); - CHECK_DIF_OK(dif_spi_device_configure(spi_device, spi_device_config)); - - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericRxFull, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericRxWatermark, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericTxWatermark, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericRxError, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericRxOverflow, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericTxUnderflow, kDifToggleEnabled)); - - // Initialize the volatile irq variables. - for (int i = 0; i < SPI_DEVICE_NUM_IRQS; i++) { - expected_irqs[i] = false; - fired_irqs[i] = false; - } -} - -/** - * Initializes PLIC and enables the relevant SPI DEVICE interrupts. - */ -static void plic_init_with_irqs(mmio_region_t base_addr, dif_rv_plic_t *plic) { - LOG_INFO("Initializing the PLIC."); - - CHECK_DIF_OK(dif_rv_plic_init(base_addr, plic)); - - // Set the priority of SPI DEVICE interrupts at PLIC to be >=1 (so ensure the - // target does get interrupted). - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow, - kDifRvPlicMaxPriority)); - - // Set the threshold for the Ibex to 0. - CHECK_DIF_OK( - dif_rv_plic_target_set_threshold(plic, kTopEarlgreyPlicTargetIbex0, 0x0)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); -} - -static bool exp_irqs_fired(void) { - return fired_irqs[kDifSpiDeviceIrqGenericRxWatermark] && - fired_irqs[kDifSpiDeviceIrqGenericTxWatermark] && - fired_irqs[kDifSpiDeviceIrqGenericRxOverflow] && - fired_irqs[kDifSpiDeviceIrqGenericTxUnderflow] && - fired_irqs[kDifSpiDeviceIrqGenericRxFull]; -} - -static void sync_testbench(void) { - // Set WFI status for testbench synchronization, - // no actual WFI instruction is issued. - test_status_set(kTestStatusInWfi); - test_status_set(kTestStatusInTest); -} - -enum { - kTimeoutUs = 1000, -}; - -static bool execute_test(dif_spi_device_handle_t *spi_device) { - LOG_INFO("Executing the test."); - - size_t bytes_transferred = 0; - CHECK_DIF_OK(dif_spi_device_send(spi_device, spi_device_tx_data, - SPI_DEVICE_DATASET_SIZE, - &bytes_transferred)); - CHECK(!exp_irqs_fired()); - sync_testbench(); - CHECK(bytes_transferred == SPI_DEVICE_DATASET_SIZE, - "SPI_DEVICE TX_FIFO transferred bytes mismatched: {act: %d, exp: %d}", - bytes_transferred, SPI_DEVICE_DATASET_SIZE); - LOG_INFO("Transferred %d bytes to SPI_DEVICE TX_FIFO.", bytes_transferred); - - CHECK_DIF_OK(dif_spi_device_set_irq_levels( - spi_device, SPI_DEVICE_DATASET_SIZE, SPI_DEVICE_DATASET_SIZE / 2)); - expected_irqs[kDifSpiDeviceIrqGenericTxWatermark] = true; - - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericTxWatermark] && - expected_irqs[kDifSpiDeviceIrqGenericTxWatermark], - kTimeoutUs); - - // Set rx tx level back to default value so TxBelowLevel irq won't trigger. - CHECK_DIF_OK( - dif_spi_device_set_irq_levels(spi_device, SPI_DEVICE_DATASET_SIZE, 0)); - expected_irqs[kDifSpiDeviceIrqGenericTxWatermark] = false; - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark] = true; - LOG_INFO("SPI_DEVICE tx_below_level interrupt fired."); - - // Wait for SPI_HOST to send 128 bytes and trigger RxAboveLevel irq. - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxWatermark] && - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark], - kTimeoutUs); - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark] = false; - LOG_INFO("SPI_DEVICE rx_above_level interrupt fired."); - - // When 128 bytes received in RX_FIFO from SPI_HOST, - // read out and compare against the expected data. - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxWatermark], kTimeoutUs); - size_t bytes_recved = 0; - uint8_t spi_device_rx_data[SPI_DEVICE_DATASET_SIZE]; - CHECK_DIF_OK(dif_spi_device_recv(spi_device, spi_device_rx_data, - SPI_DEVICE_DATASET_SIZE, &bytes_recved)); - CHECK(bytes_recved == SPI_DEVICE_DATASET_SIZE, - "SPI_DEVICE RX_FIFO recvd bytes mismatched: {act: %d, exp: %d}", - bytes_recved, SPI_DEVICE_DATASET_SIZE); - LOG_INFO("Received %d bytes from SPI_DEVICE RX_FIFO.", bytes_recved); - - expected_irqs[kDifSpiDeviceIrqGenericTxUnderflow] = true; - fired_irqs[kDifSpiDeviceIrqGenericRxWatermark] = false; - - // Check data consistency. - LOG_INFO("Checking the received SPI_HOST RX_FIFO data for consistency."); - CHECK_ARRAYS_EQ(spi_device_rx_data, exp_spi_device_rx_data, - SPI_DEVICE_DATASET_SIZE); - - sync_testbench(); - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericTxUnderflow], kTimeoutUs); - LOG_INFO("SPI_DEVICE Tx underflow fired."); - - // expect SPI_HOST to send another 1024 bytes to fill RX SRAM FIFO. - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark] = true; - expected_irqs[kDifSpiDeviceIrqGenericTxUnderflow] = false; - - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxWatermark], kTimeoutUs); - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark] = false; - expected_irqs[kDifSpiDeviceIrqGenericRxFull] = true; - LOG_INFO("SPI_DEVICE RX Above level interrupt fired."); - - // After RX SRAM FIFO full, expect RX async FIFO overflow irq. - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxFull] && - !fired_irqs[kDifSpiDeviceIrqGenericRxOverflow], - kTimeoutUs); - LOG_INFO("SPI_DEVICE RX_FIFO full interrupt fired."); - - expected_irqs[kDifSpiDeviceIrqGenericRxFull] = false; - expected_irqs[kDifSpiDeviceIrqGenericRxOverflow] = true; - sync_testbench(); - // After RX SRAM FIFO full, expect RX async FIFO overflow irq. - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxOverflow], kTimeoutUs); - LOG_INFO("SPI_DEVICE RX_FIFO Overflow interrupt fired."); - - CHECK(exp_irqs_fired()); - - return true; -} - -OTTF_DEFINE_TEST_CONFIG(); - -bool test_main(void) { - mmio_region_t spi_device_base_addr = - mmio_region_from_addr(TOP_EARLGREY_SPI_DEVICE_BASE_ADDR); - dif_spi_device_config_t spi_device_config = { - .clock_polarity = kDifSpiDeviceEdgePositive, - .data_phase = kDifSpiDeviceEdgeNegative, - .tx_order = kDifSpiDeviceBitOrderMsbToLsb, - .rx_order = kDifSpiDeviceBitOrderMsbToLsb, - .device_mode = kDifSpiDeviceModeGeneric, - .mode_cfg = - { - .generic = - { - .rx_fifo_commit_wait = 63, - .rx_fifo_len = kFifoLen, - .tx_fifo_len = kFifoLen, - }, - }, - }; - - // Initialize SPI_DEVICE. - spi_device_init_with_irqs(spi_device_base_addr, &spi_device, - spi_device_config); - - mmio_region_t plic_base_addr = - mmio_region_from_addr(TOP_EARLGREY_RV_PLIC_BASE_ADDR); - // Initialize the PLIC. - plic_init_with_irqs(plic_base_addr, &plic0); - - // Enable the external IRQ at Ibex. - irq_global_ctrl(true); - irq_external_ctrl(true); - - return execute_test(&spi_device); -} diff --git a/sw/device/tests/sival/BUILD b/sw/device/tests/sival/BUILD index 3e7f4afb466c44..5e10c0108ee59b 100644 --- a/sw/device/tests/sival/BUILD +++ b/sw/device/tests/sival/BUILD @@ -52,7 +52,6 @@ test_suite( "//sw/device/tests:rv_dm_ndm_reset_req", "//sw/device/tests:rv_plic_smoketest", "//sw/device/tests:rv_timer_smoketest", - "//sw/device/tests:spi_device_smoketest", "//sw/device/tests:spi_host_winbond_flash_test", "//sw/device/tests:sram_ctrl_sleep_sram_ret_contents_no_scramble_test", "//sw/device/tests:sram_ctrl_sleep_sram_ret_contents_scramble_test", diff --git a/sw/host/tests/chip/spi_device_ottf_console/BUILD b/sw/host/tests/chip/spi_device_ottf_console/BUILD deleted file mode 100644 index 95512357daee0a..00000000000000 --- a/sw/host/tests/chip/spi_device_ottf_console/BUILD +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -load("@rules_rust//rust:defs.bzl", "rust_binary") - -package(default_visibility = ["//visibility:public"]) - -rust_binary( - name = "spi_device_ottf_console", - srcs = [ - "src/main.rs", - ], - deps = [ - "//sw/host/opentitanlib", - "//third_party/rust/crates:anyhow", - "//third_party/rust/crates:clap", - "//third_party/rust/crates:humantime", - "//third_party/rust/crates:log", - "//third_party/rust/crates:regex", - ], -) diff --git a/sw/host/tests/chip/spi_device_ottf_console/src/main.rs b/sw/host/tests/chip/spi_device_ottf_console/src/main.rs deleted file mode 100644 index 36dc45463b4d23..00000000000000 --- a/sw/host/tests/chip/spi_device_ottf_console/src/main.rs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -use anyhow::{anyhow, Result}; -use clap::Parser; -use regex::Regex; -use std::time::Duration; - -use opentitanlib::app::TransportWrapper; -use opentitanlib::console::spi::SpiConsoleDevice; -use opentitanlib::execute_test; -use opentitanlib::test_utils::init::InitializeTest; -use opentitanlib::uart::console::{ExitStatus, UartConsole}; - -#[derive(Debug, Parser)] -struct Opts { - #[command(flatten)] - init: InitializeTest, - - /// Console receive timeout. - #[arg(long, value_parser = humantime::parse_duration, default_value = "600s")] - timeout: Duration, - - /// Name of the SPI interface to connect to the OTTF console. - #[arg(long, default_value = "BOOTSTRAP")] - console_spi: String, -} - -fn spi_device_console_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> { - let mut console = UartConsole { - timeout: Some(opts.timeout), - exit_success: Some(Regex::new(r"PASS.*\n")?), - exit_failure: Some(Regex::new(r"(FAIL|FAULT).*\n")?), - newline: true, - ..Default::default() - }; - let mut stdout = std::io::stdout(); - let spi = transport.spi(&opts.console_spi)?; - let spi_console_device = SpiConsoleDevice::new(&*spi); - let _ = UartConsole::wait_for(&spi_console_device, r"Running [^\r\n]*", opts.timeout)?; - let result = console.interact(&spi_console_device, None, Some(&mut stdout))?; - match result { - ExitStatus::None | ExitStatus::CtrlC => Ok(()), - ExitStatus::Timeout => { - if console.exit_success.is_some() { - Err(anyhow!("Console timeout exceeded")) - } else { - Ok(()) - } - } - ExitStatus::ExitSuccess => { - log::info!( - "ExitSuccess({:?})", - console.captures(result).unwrap().get(0).unwrap().as_str() - ); - Ok(()) - } - ExitStatus::ExitFailure => { - log::info!( - "ExitFailure({:?})", - console.captures(result).unwrap().get(0).unwrap().as_str() - ); - Err(anyhow!("Matched exit_failure expression")) - } - } -} - -fn main() -> Result<()> { - let opts = Opts::parse(); - opts.init.init_logging(); - let transport = opts.init.init_target()?; - execute_test!(spi_device_console_test, &opts, &transport); - Ok(()) -} diff --git a/sw/host/tests/chip/spi_device_smoketest/BUILD b/sw/host/tests/chip/spi_device_smoketest/BUILD deleted file mode 100644 index 6ac94aece3ddce..00000000000000 --- a/sw/host/tests/chip/spi_device_smoketest/BUILD +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -load("@rules_rust//rust:defs.bzl", "rust_binary") - -package(default_visibility = ["//visibility:public"]) - -rust_binary( - name = "spi_device_smoketest", - srcs = [ - "src/main.rs", - ], - deps = [ - "//sw/host/opentitanlib", - "//third_party/rust/crates:anyhow", - "//third_party/rust/crates:clap", - "//third_party/rust/crates:humantime", - "//third_party/rust/crates:log", - "//third_party/rust/crates:regex", - "@crate_index//:object", - ], -) diff --git a/sw/host/tests/chip/spi_device_smoketest/src/main.rs b/sw/host/tests/chip/spi_device_smoketest/src/main.rs deleted file mode 100644 index 6b8cf26be5e8ab..00000000000000 --- a/sw/host/tests/chip/spi_device_smoketest/src/main.rs +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -use anyhow::{bail, Result}; -use clap::Parser; -use regex::Regex; -use std::fs; -use std::path::PathBuf; -use std::time::Duration; - -use opentitanlib::app::TransportWrapper; -use opentitanlib::execute_test; -use opentitanlib::io::spi::Transfer; -use opentitanlib::test_utils; -use opentitanlib::test_utils::init::InitializeTest; -use opentitanlib::uart::console::{ExitStatus, UartConsole}; - -#[derive(Debug, Parser)] -struct Opts { - #[command(flatten)] - init: InitializeTest, - - /// Console receive timeout. - #[arg(long, value_parser = humantime::parse_duration, default_value = "600s")] - timeout: Duration, - - /// Name of the SPI interface to connect to the OTTF console. - #[arg(long, default_value = "BOOTSTRAP")] - spi: String, - - /// Path to the firmware's ELF file, for querying symbol addresses. - #[arg(value_name = "FIRMWARE_ELF")] - firmware_elf: PathBuf, -} - -fn device_tx_watermark_test( - opts: &Opts, - transport: &TransportWrapper, - tx_data: &[u8], - rx_data: &[u8], -) -> Result<()> { - let uart = transport.uart("console")?; - let spi = transport.spi(&opts.spi)?; - - /* Wait sync message. */ - let _ = UartConsole::wait_for(&*uart, r"SYNC: TX_FIFO READY\r\n", opts.timeout)?; - - let mut buf = vec![0u8; tx_data.len() - 1]; - // Due to the limitations of hyper310 (it does not support `Transfer::Both`) we first send one byte in order to - // read the device rx FIFO. - spi.run_transaction(&mut [Transfer::Write(&[tx_data[0]; 1]), Transfer::Read(&mut buf)])?; - // Due to the limitations above, the first rx byte is lost in the write operation, so we need - // to do this weird comparison. - assert_eq!(&buf, &rx_data[1..]); - Ok(()) -} - -fn device_rx_watermark_test( - opts: &Opts, - transport: &TransportWrapper, - tx_data: &[u8], -) -> Result<()> { - let uart = transport.uart("console")?; - let spi = transport.spi(&opts.spi)?; - - let _ = UartConsole::wait_for(&*uart, r"SYNC: RX_FIFO READY\r\n", opts.timeout)?; - spi.run_transaction(&mut [Transfer::Write(tx_data)]) -} - -fn device_tx_underflow_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> { - let uart = transport.uart("console")?; - let spi = transport.spi(&opts.spi)?; - /* Wait sync message. */ - let _ = UartConsole::wait_for(&*uart, r"SYNC: TX_FIFO UNDERFLOW READY\r\n", opts.timeout)?; - spi.run_transaction(&mut [Transfer::Write(&[0xAA; 2])]) -} - -fn device_rx_full_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> { - let uart = transport.uart("console")?; - let spi = transport.spi(&opts.spi)?; - /* Wait sync message. */ - let _ = UartConsole::wait_for(&*uart, r"SYNC: RX_FIFO FULL READY\r\n", opts.timeout)?; - spi.run_transaction(&mut [Transfer::Write(&[0xAB; 1024])]) -} - -fn device_rx_overflow_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> { - let uart = transport.uart("console")?; - let spi = transport.spi(&opts.spi)?; - /* Wait sync message. */ - let _ = UartConsole::wait_for(&*uart, r"SYNC: RX_FIFO OVERFLOW READY\r\n", opts.timeout)?; - spi.run_transaction(&mut [Transfer::Write(&[0xB5; 64])]) -} - -fn main() -> Result<()> { - let opts = Opts::parse(); - opts.init.init_logging(); - - /* Load the ELF binary and get the expect data.*/ - let elf_binary = fs::read(&opts.firmware_elf)?; - let object = object::File::parse(&*elf_binary)?; - - let spi_device_rx_data = test_utils::object::symbol_data(&object, "spi_device_tx_data")?; - let spi_device_tx_data = test_utils::object::symbol_data(&object, "exp_spi_device_rx_data")?; - - let transport = opts.init.init_target()?; - execute_test!( - device_tx_watermark_test, - &opts, - &transport, - &spi_device_tx_data, - &spi_device_rx_data - ); - - execute_test!( - device_rx_watermark_test, - &opts, - &transport, - &spi_device_tx_data - ); - - execute_test!(device_tx_underflow_test, &opts, &transport); - - execute_test!(device_rx_full_test, &opts, &transport); - - execute_test!(device_rx_overflow_test, &opts, &transport); - - let uart = transport.uart("console")?; - let mut console = UartConsole { - timeout: Some(opts.timeout), - exit_success: Some(Regex::new(r"PASS!\r\n")?), - exit_failure: Some(Regex::new(r"FAIL:")?), - ..Default::default() - }; - - // Now watch the console for the exit conditions. - let result = console.interact(&*uart, None, Some(&mut std::io::stdout()))?; - if result != ExitStatus::ExitSuccess { - bail!("FAIL: {:?}", result); - }; - - Ok(()) -}