Add IO related tests to edacloud. Change-Id: Icf29520880b54bd118c683a564a80e816068bb49
diff --git a/hw/top_matcha/dv/chip_sim_cfg.hjson b/hw/top_matcha/dv/chip_sim_cfg.hjson index ca7e36e..5c178f4 100644 --- a/hw/top_matcha/dv/chip_sim_cfg.hjson +++ b/hw/top_matcha/dv/chip_sim_cfg.hjson
@@ -667,7 +667,7 @@ { name: chip_sw_sleep_pin_retention uvm_test_seq: chip_sw_sleep_pin_retention_vseq - sw_images: ["//sw/device/tests/sim_dv:sleep_pin_retention_test:1"] + sw_images: ["//sw/device/tests/sim_dv:sleep_pin_retention_test:1:matcha"] en_run_modes: ["sw_test_mode_test_rom"] } { @@ -826,7 +826,7 @@ { name: chip_sw_gpio uvm_test_seq: chip_sw_gpio_vseq - sw_images: ["//sw/device/tests/sim_dv:gpio_test:1"] + sw_images: ["//sw/device/tests/sim_dv:gpio_test:1:matcha"] en_run_modes: ["sw_test_mode_test_rom"] } { @@ -2017,6 +2017,7 @@ "chip_sw_csrng_smoketest", "chip_sw_dma_main_test", "chip_sw_example_flash", + "chip_sw_gpio", "chip_sw_i2c_host_tx_rx", "chip_sw_mem_test", "chip_sw_rom_ctrl_integrity_check", @@ -2070,6 +2071,7 @@ "chip_sw_flash_ctrl_access", "chip_sw_flash_ctrl_access_jitter_en", "chip_sw_flash_ctrl_access_jitter_en_reduced_freq", + "chip_sw_gpio", "chip_sw_hmac_enc", "chip_sw_hmac_smoketest", "chip_sw_i2c_host_tx_rx", @@ -2094,6 +2096,7 @@ "chip_sw_rv_timer_irq", "chip_sw_sensor_ctrl_alert", "chip_sw_sensor_ctrl_status", + "chip_sw_sleep_pin_retention", "chip_sw_smc_cam_irq_test", "chip_sw_smc_ctrl_test", "chip_sw_smc_env_test", @@ -2141,6 +2144,7 @@ "chip_sw_flash_ctrl_access", "chip_sw_flash_ctrl_access_jitter_en", "chip_sw_flash_ctrl_access_jitter_en_reduced_freq", + "chip_sw_gpio", "chip_sw_hmac_enc", "chip_sw_hmac_smoketest", "chip_sw_i2c_host_tx_rx", @@ -2171,6 +2175,7 @@ "chip_sw_rv_timer_irq", "chip_sw_sensor_ctrl_alert", "chip_sw_sensor_ctrl_status", + "chip_sw_sleep_pin_retention", "chip_sw_smc_cam_irq_test", "chip_sw_smc_ctrl_test", "chip_sw_smc_env_test",
diff --git a/hw/top_matcha/dv/env/chip_if.sv b/hw/top_matcha/dv/env/chip_if.sv index 5b576bc..6663de3 100644 --- a/hw/top_matcha/dv/env/chip_if.sv +++ b/hw/top_matcha/dv/env/chip_if.sv
@@ -404,9 +404,9 @@ // hw/top_matcha/rtl/chip_matcha_verilator.sv and // sw/device/lib/testing/pinmux_testutils.c pins_if #(.Width(NUM_GPIOS), .PullStrength("Weak")) gpios_if( - .pins({mios[top_matcha_pkg::MioPadIor10], mios[top_matcha_pkg::MioPadIoc8], + .pins({mios[top_matcha_pkg::MioPadIor10], mios[top_matcha_pkg::MioPadIod1], mios[top_matcha_pkg::MioPadIor7], mios[top_matcha_pkg::MioPadIor6], - mios[top_matcha_pkg::MioPadIoc5], mios[top_matcha_pkg::MioPadIoc9], + mios[top_matcha_pkg::MioPadIod0], mios[top_matcha_pkg::MioPadIoc9], mios[top_matcha_pkg::MioPadIoc7], mios[top_matcha_pkg::MioPadIoc2], mios[top_matcha_pkg::MioPadIoc1], mios[top_matcha_pkg::MioPadIoc0], mios[top_matcha_pkg::MioPadIoc6], mios[top_matcha_pkg::MioPadIob12],
diff --git a/hw/top_matcha/dv/env/seq_lib/chip_sw_gpio_vseq.sv b/hw/top_matcha/dv/env/seq_lib/chip_sw_gpio_vseq.sv index c6266ca..e6a5ddc 100644 --- a/hw/top_matcha/dv/env/seq_lib/chip_sw_gpio_vseq.sv +++ b/hw/top_matcha/dv/env/seq_lib/chip_sw_gpio_vseq.sv
@@ -1,3 +1,4 @@ +// Copyright 2023 Google LLC. // Copyright lowRISC contributors. // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 @@ -20,6 +21,7 @@ gpio_output_test(); // Run the GPIO input tests. + cfg.chip_vif.gpios_if.disconnect(); gpio_input_test(); endtask
diff --git a/sw/device/lib/testing/pinmux_testutils.c b/sw/device/lib/testing/pinmux_testutils.c index ea18a08..d71a23e 100644 --- a/sw/device/lib/testing/pinmux_testutils.c +++ b/sw/device/lib/testing/pinmux_testutils.c
@@ -17,41 +17,41 @@ // hw/top_matcha/rtl/chip_matcha_verilator.sv and // hw/top_matcha/dv/env/chip_if.sv const dif_pinmux_index_t kPinmuxTestutilsGpioInselPins[kDifGpioNumPins] = { - kTopMatchaPinmuxInselIoa0, kTopMatchaPinmuxInselIoa1, - kTopMatchaPinmuxInselIoa2, kTopMatchaPinmuxInselIoa3, - kTopMatchaPinmuxInselIoa4, kTopMatchaPinmuxInselIoa5, - kTopMatchaPinmuxInselIoa6, kTopMatchaPinmuxInselIoa7, - kTopMatchaPinmuxInselIoa8, kTopMatchaPinmuxInselIob0, - kTopMatchaPinmuxInselIob1, kTopMatchaPinmuxInselIob2, - kTopMatchaPinmuxInselIob3, kTopMatchaPinmuxInselIob4, - kTopMatchaPinmuxInselIob5, kTopMatchaPinmuxInselIob6, - kTopMatchaPinmuxInselIob7, kTopMatchaPinmuxInselIob8, - kTopMatchaPinmuxInselIob10, kTopMatchaPinmuxInselIob11, - kTopMatchaPinmuxInselIob12, kTopMatchaPinmuxInselIoc6, - kTopMatchaPinmuxInselIoc0, kTopMatchaPinmuxInselIoc1, - kTopMatchaPinmuxInselIoc2, kTopMatchaPinmuxInselIoc7, - kTopMatchaPinmuxInselIoc9, kTopMatchaPinmuxInselIoc5, - kTopMatchaPinmuxInselIor6, kTopMatchaPinmuxInselIor7, - kTopMatchaPinmuxInselIoc8, kTopMatchaPinmuxInselIor10, + kTopMatchaPinmuxInselIoa0, kTopMatchaPinmuxInselIoa1, + kTopMatchaPinmuxInselIoa2, kTopMatchaPinmuxInselIoa3, + kTopMatchaPinmuxInselIoa4, kTopMatchaPinmuxInselIoa5, + kTopMatchaPinmuxInselIoa6, kTopMatchaPinmuxInselIoa7, + kTopMatchaPinmuxInselIoa8, kTopMatchaPinmuxInselIob0, + kTopMatchaPinmuxInselIob1, kTopMatchaPinmuxInselIob2, + kTopMatchaPinmuxInselIob3, kTopMatchaPinmuxInselIob4, + kTopMatchaPinmuxInselIob5, kTopMatchaPinmuxInselIob6, + kTopMatchaPinmuxInselIob7, kTopMatchaPinmuxInselIob8, + kTopMatchaPinmuxInselIob10, kTopMatchaPinmuxInselIob11, + kTopMatchaPinmuxInselIob12, kTopMatchaPinmuxInselIoc6, + kTopMatchaPinmuxInselIoc0, kTopMatchaPinmuxInselIoc1, + kTopMatchaPinmuxInselIoc2, kTopMatchaPinmuxInselIoc7, + kTopMatchaPinmuxInselIoc9, kTopMatchaPinmuxInselIod0, + kTopMatchaPinmuxInselIor6, kTopMatchaPinmuxInselIor7, + kTopMatchaPinmuxInselIod1, kTopMatchaPinmuxInselIor10, }; const dif_pinmux_index_t kPinmuxTestutilsGpioMioOutPins[kDifGpioNumPins] = { - kTopMatchaPinmuxMioOutIoa0, kTopMatchaPinmuxMioOutIoa1, - kTopMatchaPinmuxMioOutIoa2, kTopMatchaPinmuxMioOutIoa3, - kTopMatchaPinmuxMioOutIoa4, kTopMatchaPinmuxMioOutIoa5, - kTopMatchaPinmuxMioOutIoa6, kTopMatchaPinmuxMioOutIoa7, - kTopMatchaPinmuxMioOutIoa8, kTopMatchaPinmuxMioOutIob0, - kTopMatchaPinmuxMioOutIob1, kTopMatchaPinmuxMioOutIob2, - kTopMatchaPinmuxMioOutIob3, kTopMatchaPinmuxMioOutIob4, - kTopMatchaPinmuxMioOutIob5, kTopMatchaPinmuxMioOutIob6, - kTopMatchaPinmuxMioOutIob7, kTopMatchaPinmuxMioOutIob8, - kTopMatchaPinmuxMioOutIob10, kTopMatchaPinmuxMioOutIob11, - kTopMatchaPinmuxMioOutIob12, kTopMatchaPinmuxMioOutIoc6, - kTopMatchaPinmuxMioOutIoc0, kTopMatchaPinmuxMioOutIoc1, - kTopMatchaPinmuxMioOutIoc2, kTopMatchaPinmuxMioOutIoc7, - kTopMatchaPinmuxMioOutIoc9, kTopMatchaPinmuxMioOutIoc5, - kTopMatchaPinmuxMioOutIor6, kTopMatchaPinmuxMioOutIor7, - kTopMatchaPinmuxMioOutIoc8, kTopMatchaPinmuxMioOutIor10, + kTopMatchaPinmuxMioOutIoa0, kTopMatchaPinmuxMioOutIoa1, + kTopMatchaPinmuxMioOutIoa2, kTopMatchaPinmuxMioOutIoa3, + kTopMatchaPinmuxMioOutIoa4, kTopMatchaPinmuxMioOutIoa5, + kTopMatchaPinmuxMioOutIoa6, kTopMatchaPinmuxMioOutIoa7, + kTopMatchaPinmuxMioOutIoa8, kTopMatchaPinmuxMioOutIob0, + kTopMatchaPinmuxMioOutIob1, kTopMatchaPinmuxMioOutIob2, + kTopMatchaPinmuxMioOutIob3, kTopMatchaPinmuxMioOutIob4, + kTopMatchaPinmuxMioOutIob5, kTopMatchaPinmuxMioOutIob6, + kTopMatchaPinmuxMioOutIob7, kTopMatchaPinmuxMioOutIob8, + kTopMatchaPinmuxMioOutIob10, kTopMatchaPinmuxMioOutIob11, + kTopMatchaPinmuxMioOutIob12, kTopMatchaPinmuxMioOutIoc6, + kTopMatchaPinmuxMioOutIoc0, kTopMatchaPinmuxMioOutIoc1, + kTopMatchaPinmuxMioOutIoc2, kTopMatchaPinmuxMioOutIoc7, + kTopMatchaPinmuxMioOutIoc9, kTopMatchaPinmuxMioOutIod0, + kTopMatchaPinmuxMioOutIor6, kTopMatchaPinmuxMioOutIor7, + kTopMatchaPinmuxMioOutIod1, kTopMatchaPinmuxMioOutIor10, }; void pinmux_testutils_init(dif_pinmux_t *pinmux) { @@ -104,3 +104,5 @@ CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIoc11, kTopMatchaPinmuxOutselSmcUartTx)); } + +uint32_t pinmux_testutils_get_testable_gpios_mask(void) { return 0xffffffff; }
diff --git a/sw/device/lib/testing/pinmux_testutils.h b/sw/device/lib/testing/pinmux_testutils.h index 984b27f..657d6f0 100644 --- a/sw/device/lib/testing/pinmux_testutils.h +++ b/sw/device/lib/testing/pinmux_testutils.h
@@ -25,4 +25,12 @@ extern const dif_pinmux_index_t kPinmuxTestutilsGpioInselPins[kDifGpioNumPins]; extern const dif_pinmux_index_t kPinmuxTestutilsGpioMioOutPins[kDifGpioNumPins]; +/** + * Returns the mask of testable GPIO pins. + * + * Returns a simulation-device-specific mask that enables testing of only a + * subset of GPIOs depending on the IO allocation limitations. + */ +uint32_t pinmux_testutils_get_testable_gpios_mask(void); + #endif // MATCHA_SW_DEVICE_LIB_TESTING_PINMUX_TESTUTILS_H_
diff --git a/sw/device/tests/sim_dv/BUILD b/sw/device/tests/sim_dv/BUILD index 9bec762..66a73fd 100644 --- a/sw/device/tests/sim_dv/BUILD +++ b/sw/device/tests/sim_dv/BUILD
@@ -119,6 +119,22 @@ ], ) +matcha_dv_test( + name = "sleep_pin_retention_test", + srcs = ["sleep_pin_retention_test.c"], + deps = [ + "//sw/device/lib/dif:pinmux", + "//sw/device/lib/dif:rv_plic_sec", + "//sw/device/lib/testing:isr_testutils", + "//sw/device/tests:test_dv_lib", + "@lowrisc_opentitan//sw/device/lib/dif:gpio", + "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr", + "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils", + "@lowrisc_opentitan//sw/device/lib/testing:rand_testutils", + "@lowrisc_opentitan//sw/device/lib/testing:rv_plic_testutils", + ], +) + ################################################################################ # Place the Opentitan-sourced DV test below. # # Opentitan DV binary build flow does not support centOS7, so we pull the # @@ -243,3 +259,15 @@ "@lowrisc_opentitan//sw/device/lib/testing:rstmgr_testutils", ], ) + +matcha_dv_test( + name = "gpio_test", + srcs = ["@lowrisc_opentitan//sw/device/tests/sim_dv:gpio_test.c"], + deps = [ + "//sw/device/lib/dif:rv_plic_sec", + "//sw/device/lib/testing:pinmux_testutils", + "//sw/device/tests:test_dv_lib_opentitan", + "@lowrisc_opentitan//sw/device/lib/dif:gpio", + "@lowrisc_opentitan//sw/device/lib/testing:rv_plic_testutils", + ], +)
diff --git a/sw/device/tests/sim_dv/sleep_pin_retention_test.c b/sw/device/tests/sim_dv/sleep_pin_retention_test.c new file mode 100644 index 0000000..750e90e --- /dev/null +++ b/sw/device/tests/sim_dv/sleep_pin_retention_test.c
@@ -0,0 +1,214 @@ +// Copyright 2023 Google LLC. +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#include "hw/top_matcha/sw/autogen/top_matcha.h" +#include "sw/device/lib/base/mmio.h" +#include "sw/device/lib/dif/dif_gpio.h" +#include "sw/device/lib/dif/dif_pinmux.h" +#include "sw/device/lib/dif/dif_pwrmgr.h" +#include "sw/device/lib/dif/dif_rv_plic.h" +#include "sw/device/lib/runtime/irq.h" +#include "sw/device/lib/runtime/log.h" +#include "sw/device/lib/testing/autogen/isr_testutils.h" +#include "sw/device/lib/testing/pwrmgr_testutils.h" +#include "sw/device/lib/testing/rand_testutils.h" +#include "sw/device/lib/testing/rv_plic_testutils.h" +#include "sw/device/lib/testing/test_framework/check.h" +#include "sw/device/lib/testing/test_framework/ottf_main.h" + +OTTF_DEFINE_TEST_CONFIG(); + +// PLIC structures +static const uint32_t kPlicTarget = kTopMatchaPlicTargetIbex0; +static dif_gpio_t gpio; +static dif_pwrmgr_t pwrmgr; +static dif_pinmux_t pinmux; +static dif_pwrmgr_domain_config_t pwrmgr_domain_cfg; +static dif_rv_plic_t plic; + +static plic_isr_ctx_t plic_ctx = {.rv_plic = &plic, .hart_id = kPlicTarget}; +static pwrmgr_isr_ctx_t pwrmgr_isr_ctx = { + .pwrmgr = &pwrmgr, + .plic_pwrmgr_start_irq_id = kTopMatchaPlicIrqIdPwrmgrAonWakeup, + .expected_irq = kDifPwrmgrIrqWakeup, + .is_only_irq = true}; + +// SV randomizes the round of entering/exiting sleep then set this volatile +// variable via backdoor_overwrite. +static volatile const uint8_t kRounds = 2; + +// SW testcode randomly chooses the value for 8 GPIO pins (pins are fixed) then +// invert the value for retention. SW will sends the value to SV testbench via +// LOG_INFO(). +static const uint8_t kGpioVal = 0x00; + +// To wakeup and maintain GPIO, for now test enters to normal sleep only. +static const bool deepPowerdown = false; + +// Num of GPIO Pads to test +enum { kNumGpioPads = 8 }; + +/** + * External interrupt handler. + */ +void ottf_external_isr(void) { + dif_pwrmgr_irq_t irq_id; + top_matcha_plic_peripheral_t peripheral; + + isr_testutils_pwrmgr_isr(plic_ctx, pwrmgr_isr_ctx, &peripheral, &irq_id); + + // Check that both the peripheral and the irq id is correct + CHECK(peripheral == kTopMatchaPlicPeripheralPwrmgrAon, + "IRQ peripheral: %d is incorrect", peripheral); + CHECK(irq_id == kDifPwrmgrIrqWakeup, "IRQ ID: %d is incorrect", irq_id); + + // Clear PINMUX WKUP_CAUSE reg + CHECK_DIF_OK(dif_pinmux_wakeup_cause_clear(&pinmux)); +} + +/** + * A round of GPIO[7:0] retention value test. + * + * The test sequence is: + * + * 1. Randomly choose GPIO[7:0] value using rand_testutils. + * 2. Drive GPIO with the chosen value. + * 3. Send the chosen values to SV via LOG_INFO. + * 4. Configure PINMUX Retention value opposit to the chosen value for + * GPIO[7:0]. + * 5. Initiate sleep mode (assuming pinmux pin wake up has been configured.) + * 6. WFI() + * 7. At this point, chip has been waken up by DV. Send a log to DV that chip + * has waken up. + * + * DV env checks all PIN value. SW simply drives the GPIO and invert the value + * for retention. + */ +void gpio_test(dif_pwrmgr_t *pwrmgr, dif_pinmux_t *pinmux, dif_gpio_t *gpio, + int round) { + uint8_t gpio_val = 0; + dif_pinmux_pad_kind_t pad_kind; + dif_pinmux_sleep_mode_t pad_mode; + + LOG_INFO("Current Test Round: %1d", round); + + // 1. Randomly choose GPIO value + gpio_val = rand_testutils_gen32_range(0, 255); + + // 2. Drive GPIO with the chosen value. + CHECK_DIF_OK(dif_gpio_write_masked(gpio, (dif_gpio_mask_t)0x000000FF, + (dif_gpio_state_t)gpio_val)); + + // 3. Send the chosen value to SV via LOG_INFO. + // + // The format is: + // + // Chosen GPIO value: %2x + LOG_INFO("Chosen GPIO value: %2x", gpio_val); + + // 4. Configure PINMUX Retention value opposite to the chosen value. + pad_kind = kDifPinmuxPadKindMio; + for (int i = 0; i < kNumGpioPads; i++) { + // GPIO are assigned starting from MIO0 + pad_mode = ((gpio_val >> i) & 0x1) ? kDifPinmuxSleepModeLow + : kDifPinmuxSleepModeHigh; + CHECK_DIF_OK(dif_pinmux_pad_sleep_enable( + pinmux, kTopMatchaPinmuxMioOutIoa0 + i, pad_kind, pad_mode)); + } + + // 5. Initiate sleep mode + pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceThree, + pwrmgr_domain_cfg); + // 6. WFI() + LOG_INFO("Entering low power mode."); + wait_for_interrupt(); + + // 7. Turn-off retention. + for (int i = 0; i < kNumGpioPads; i++) { + CHECK_DIF_OK(dif_pinmux_pad_sleep_clear_state( + pinmux, kTopMatchaPinmuxMioOutIoa0 + i, pad_kind)); + } +} + +/** + * Configure GPIO + * + * gpio_init() configures first 8 MIO PADs to GPIO[7:0]. + */ +void gpio_init(const dif_pinmux_t *pinmux, const dif_gpio_t *gpio) { + // Drive GPIO first + CHECK_DIF_OK( + dif_gpio_output_set_enabled_all(gpio, (dif_gpio_state_t)0x000000FFu)); + CHECK_DIF_OK(dif_gpio_write_masked(gpio, (dif_gpio_mask_t)0x000000FF, + (dif_gpio_state_t)0x00000000)); + + // Configure PINMUX to GPIO + for (int i = 0; i < kNumGpioPads; i++) { + CHECK_DIF_OK(dif_pinmux_input_select( + pinmux, kTopMatchaPinmuxPeripheralInGpioGpio0 + i, + kTopMatchaPinmuxInselIoa0 + i)); + CHECK_DIF_OK(dif_pinmux_output_select(pinmux, + kTopMatchaPinmuxMioOutIoa0 + i, + kTopMatchaPinmuxOutselGpioGpio0 + i)); + } +} + +bool test_main(void) { + bool result = true; + + dif_pinmux_index_t detector; + dif_pinmux_wakeup_config_t wakeup_cfg; + + // Default Deep Power Down + + // Enable global and external IRQ at Ibex. + irq_global_ctrl(true); + irq_external_ctrl(true); + + // Initialize power manager + CHECK_DIF_OK(dif_pwrmgr_init( + mmio_region_from_addr(TOP_MATCHA_PWRMGR_AON_BASE_ADDR), &pwrmgr)); + CHECK_DIF_OK(dif_rv_plic_init( + mmio_region_from_addr(TOP_MATCHA_RV_PLIC_BASE_ADDR), &plic)); + CHECK_DIF_OK(dif_pinmux_init( + mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux)); + CHECK_DIF_OK( + dif_gpio_init(mmio_region_from_addr(TOP_MATCHA_GPIO_BASE_ADDR), &gpio)); + + // Enable all the AON interrupts used in this test. + rv_plic_testutils_irq_range_enable(&plic, kPlicTarget, + kTopMatchaPlicIrqIdPwrmgrAonWakeup, + kTopMatchaPlicIrqIdPwrmgrAonWakeup); + // Enable pwrmgr interrupt + CHECK_DIF_OK(dif_pwrmgr_irq_set_enabled(&pwrmgr, 0, kDifToggleEnabled)); + + // Wakeup configs + wakeup_cfg.mode = kDifPinmuxWakeupModePositiveEdge; + wakeup_cfg.signal_filter = false; + wakeup_cfg.pad_type = 0; // MIO + wakeup_cfg.pad_select = kTopMatchaPinmuxInselIoa8; // MIO08 + + // Configure Wakeup Detector 0 + CHECK_DIF_OK(dif_pinmux_wakeup_detector_enable(&pinmux, 0, wakeup_cfg)); + + if (deepPowerdown == false) { + // Configure Normal Sleep + pwrmgr_domain_cfg = kDifPwrmgrDomainOptionMainPowerInLowPower | + kDifPwrmgrDomainOptionUsbClockInActivePower; + } + + LOG_INFO("Num Rounds: %3d", kRounds); + + // Select IOA0:IOA7 to GPIO + gpio_init(&pinmux, &gpio); + + // Set wakeup condition. Always use GPIO[8] for Pinmux PIN Wakeup. + + for (int i = kRounds - 1; i >= 0; i--) { + gpio_test(&pwrmgr, &pinmux, &gpio, i); + } + + return result; +}