Add 3 tests to edacloud Change-Id: Ie8b58b0db4dc2aa1c4218825183299be82be3e39
diff --git a/hw/top_matcha/dv/chip_sim_cfg.hjson b/hw/top_matcha/dv/chip_sim_cfg.hjson index cb83396..5889a2c 100644 --- a/hw/top_matcha/dv/chip_sim_cfg.hjson +++ b/hw/top_matcha/dv/chip_sim_cfg.hjson
@@ -1148,7 +1148,7 @@ { name: chip_sw_pwrmgr_sleep_disabled uvm_test_seq: chip_sw_base_vseq - sw_images: ["//sw/device/tests:pwrmgr_sleep_disabled_test:1"] + sw_images: ["//sw/device/tests:pwrmgr_sleep_disabled_test:1:matcha"] en_run_modes: ["sw_test_mode_test_rom"] } { @@ -1219,7 +1219,7 @@ { name: chip_sw_pwrmgr_wdog_reset uvm_test_seq: chip_sw_base_vseq - sw_images: ["//sw/device/tests:pwrmgr_wdog_reset_reqs_test:1"] + sw_images: ["//sw/device/tests:pwrmgr_wdog_reset_reqs_test:1:matcha"] en_run_modes: ["sw_test_mode_test_rom"] run_opts: ["+sw_test_timeout_ns=18_000_000"] } @@ -1600,7 +1600,7 @@ { name: chip_sw_sleep_sram_ret_contents uvm_test_seq: chip_sw_base_vseq - sw_images: ["//sw/device/tests:sram_ctrl_sleep_sram_ret_contents_test:1"] + sw_images: ["//sw/device/tests:sram_ctrl_sleep_sram_ret_contents_test:1:matcha"] en_run_modes: ["sw_test_mode_test_rom"] run_opts: ["+sw_test_timeout_ns=20_000_000", "+en_scb_tl_err_chk=0"] } @@ -2151,8 +2151,10 @@ "chip_sw_otp_ctrl_smoketest", "chip_sw_pwrmgr_deep_sleep_power_glitch_reset", "chip_sw_pwrmgr_normal_sleep_all_wake_ups" + "chip_sw_pwrmgr_sleep_disabled", "chip_sw_pwrmgr_sleep_power_glitch_reset", "chip_sw_pwrmgr_sleep_sensor_ctrl_alert_wakeup", + "chip_sw_pwrmgr_wdog_reset", "chip_sw_rom_ctrl_integrity_check", "chip_sw_rstmgr_cpu_info", "chip_sw_rstmgr_smoketest", @@ -2170,6 +2172,7 @@ "chip_sw_sleep_pin_retention", "chip_sw_sleep_pin_wake", "chip_sw_sleep_pwm_pulses", + "chip_sw_sleep_sram_ret_contents", "chip_sw_smc_cam_irq_test", "chip_sw_smc_ctrl_test", "chip_sw_smc_env_test", @@ -2270,8 +2273,10 @@ "chip_sw_pwrmgr_random_sleep_all_reset_reqs", "chip_sw_pwrmgr_random_sleep_all_wake_ups", "chip_sw_pwrmgr_random_sleep_power_glitch_reset", + "chip_sw_pwrmgr_sleep_disabled", "chip_sw_pwrmgr_sleep_power_glitch_reset", "chip_sw_pwrmgr_sleep_sensor_ctrl_alert_wakeup", + "chip_sw_pwrmgr_wdog_reset", "chip_sw_rom_ctrl_integrity_check", "chip_sw_rstmgr_alert_info", "chip_sw_rstmgr_cpu_info", @@ -2290,6 +2295,7 @@ "chip_sw_sleep_pin_retention", "chip_sw_sleep_pin_wake", "chip_sw_sleep_pwm_pulses", + "chip_sw_sleep_sram_ret_contents", "chip_sw_smc_cam_irq_test", "chip_sw_smc_ctrl_test", "chip_sw_smc_env_test",
diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD index 63262f8..c012506 100644 --- a/sw/device/tests/BUILD +++ b/sw/device/tests/BUILD
@@ -1198,6 +1198,54 @@ ], ) +matcha_dv_test( + name = "sram_ctrl_sleep_sram_ret_contents_test", + srcs = ["sram_ctrl_sleep_sram_ret_contents_test.c"], + deps = [ + ":test_dv_lib", + "//sw/device/lib/dif:rstmgr", + "//sw/device/lib/testing:isr_testutils", + "@lowrisc_opentitan//sw/device/lib/dif:aon_timer", + "@lowrisc_opentitan//sw/device/lib/dif:flash_ctrl", + "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr", + "@lowrisc_opentitan//sw/device/lib/testing:aon_timer_testutils", + "@lowrisc_opentitan//sw/device/lib/testing:flash_ctrl_testutils", + "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils", + "@lowrisc_opentitan//sw/device/lib/testing:rstmgr_testutils", + "@lowrisc_opentitan//sw/device/lib/testing:rv_plic_testutils", + "@lowrisc_opentitan//sw/device/lib/testing:sram_ctrl_testutils", + "@lowrisc_opentitan//sw/device/silicon_creator/lib/drivers:retention_sram", + ], +) + +matcha_dv_test( + name = "pwrmgr_wdog_reset_reqs_test", + srcs = ["@lowrisc_opentitan//sw/device/tests:pwrmgr_wdog_reset_reqs_test.c"], + deps = [ + ":test_dv_lib_opentitan", + "//sw/device/lib/dif:rstmgr", + "@lowrisc_opentitan//sw/device/lib/base:math", + "@lowrisc_opentitan//sw/device/lib/dif:aon_timer", + "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr", + "@lowrisc_opentitan//sw/device/lib/testing:aon_timer_testutils", + "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils", + "@lowrisc_opentitan//sw/device/lib/testing:rstmgr_testutils", + ], +) + +matcha_dv_test( + name = "pwrmgr_sleep_disabled_test", + srcs = ["@lowrisc_opentitan//sw/device/tests:pwrmgr_sleep_disabled_test.c"], + deps = [ + ":test_dv_lib_opentitan", + "//sw/device/lib/dif:rv_plic_sec", + "@lowrisc_opentitan//sw/device/lib/dif:aon_timer", + "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr", + "@lowrisc_opentitan//sw/device/lib/testing:aon_timer_testutils", + "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils", + ], +) + # Smoke tests matcha_dv_test( name = "aes_smoketest",
diff --git a/sw/device/tests/sram_ctrl_sleep_sram_ret_contents_test.c b/sw/device/tests/sram_ctrl_sleep_sram_ret_contents_test.c new file mode 100644 index 0000000..d9d3f07 --- /dev/null +++ b/sw/device/tests/sram_ctrl_sleep_sram_ret_contents_test.c
@@ -0,0 +1,266 @@ +// 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_aon_timer.h" +#include "sw/device/lib/dif/dif_flash_ctrl.h" +#include "sw/device/lib/dif/dif_pwrmgr.h" +#include "sw/device/lib/dif/dif_rstmgr.h" +#include "sw/device/lib/runtime/irq.h" +#include "sw/device/lib/runtime/log.h" +#include "sw/device/lib/testing/aon_timer_testutils.h" +#include "sw/device/lib/testing/autogen/isr_testutils.h" +#include "sw/device/lib/testing/flash_ctrl_testutils.h" +#include "sw/device/lib/testing/pwrmgr_testutils.h" +#include "sw/device/lib/testing/rstmgr_testutils.h" +#include "sw/device/lib/testing/rv_plic_testutils.h" +#include "sw/device/lib/testing/sram_ctrl_testutils.h" +#include "sw/device/lib/testing/test_framework/check.h" +#include "sw/device/lib/testing/test_framework/ottf_main.h" +#include "sw/device/silicon_creator/lib/drivers/retention_sram.h" + +enum { + /** + * Retention SRAM start address (inclusive). + */ + kRetSramBaseAddr = TOP_MATCHA_SRAM_CTRL_RET_AON_RAM_BASE_ADDR, + + kRetSramOwnerAddr = + kRetSramBaseAddr + offsetof(retention_sram_t, reserved_owner), + kRetRamLastAddr = + kRetSramBaseAddr + TOP_MATCHA_SRAM_CTRL_RET_AON_RAM_SIZE_BYTES - 1, + + kTestBufferSizeWords = 16, +}; + +OTTF_DEFINE_TEST_CONFIG(); + +static dif_rv_plic_t rv_plic; +static dif_aon_timer_t aon_timer; +static dif_pwrmgr_t pwrmgr; +static dif_rstmgr_t rstmgr; +static plic_isr_ctx_t plic_ctx = {.rv_plic = &rv_plic, + .hart_id = kTopMatchaPlicTargetIbex0}; +static pwrmgr_isr_ctx_t pwrmgr_isr_ctx = { + .pwrmgr = &pwrmgr, + .plic_pwrmgr_start_irq_id = kTopMatchaPlicIrqIdPwrmgrAonWakeup, + .expected_irq = kDifPwrmgrIrqWakeup, + .is_only_irq = true}; + +// Random data to read/write to/from retention SRAM. +const uint32_t kTestData[kTestBufferSizeWords] = { + 0xe647e5d5, 0x4b5fe6f6, 0x1608a98a, 0x5e347116, 0xb2dc5e92, 0x899e3c0f, + 0xc98295c2, 0x0fa84434, 0x15747561, 0xfecb5aa1, 0x7a78bb8c, 0x8f9c5d0f, + 0x49338fbd, 0x093e82cb, 0xaaa58121, 0x5b806f96, +}; + +typedef struct { + bool do_write; + bool is_equal; +} check_config_t; + +// this is preserved across resets. Flash default value is all 1s, +// can be written to 0 without an erase, so name this `non` scramble. +// flash doesn't support byte write, hence define it to a 32 bit int. +OT_SECTION(".non_volatile_scratch") uint32_t ret_non_scrambled; + +static void retention_sram_check(check_config_t config) { + if (config.do_write) { + sram_ctrl_testutils_write( + kRetSramOwnerAddr, + (sram_ctrl_testutils_data_t){.words = kTestData, + .len = kTestBufferSizeWords}); + } + + uint32_t tmp_buffer[kTestBufferSizeWords]; + memcpy(tmp_buffer, (uint8_t *)kRetSramOwnerAddr, sizeof(tmp_buffer)); + + if (config.is_equal) { + CHECK_ARRAYS_EQ(tmp_buffer, kTestData, kTestBufferSizeWords); + } else { + CHECK_ARRAYS_NE(tmp_buffer, kTestData, kTestBufferSizeWords); + } +} + +/** + * Override internal interrupt handler to handle the ECC errors when reading the + * scrambled memory. + */ +void ottf_internal_isr(void) {} + +/** + * Override external interrupt handler to handle the normal sleep IRQ. + */ +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); + + LOG_INFO("Receive irq in normal sleep"); + // Check that both the peripheral and the irq id are correct. + CHECK(peripheral == kTopMatchaPlicPeripheralPwrmgrAon, + "IRQ peripheral: %d is incorrect", peripheral); + CHECK(irq_id == kDifPwrmgrIrqWakeup, "IRQ ID: %d is incorrect", irq_id); +} + +// test these 2 cases: +// normal sleep, no scrambling -> data preserved +// normal sleep, with scrambling -> data preserved +void test_ret_sram_in_normal_sleep(void) { + // Write data to retention SRAM and readback (to test basic functionality.) + retention_sram_check((check_config_t){.do_write = true, .is_equal = true}); + + // set up wakeup timer + aon_timer_testutils_wakeup_config(&aon_timer, 20); + // Enable all the AON interrupts used in this test. + rv_plic_testutils_irq_range_enable(&rv_plic, kTopMatchaPlicTargetIbex0, + kTopMatchaPlicIrqIdPwrmgrAonWakeup, + kTopMatchaPlicIrqIdPwrmgrAonWakeup); + CHECK_DIF_OK(dif_pwrmgr_irq_set_enabled(&pwrmgr, 0, kDifToggleEnabled)); + + // Normal sleep. + pwrmgr_testutils_enable_low_power( + &pwrmgr, /*wakeups=*/kDifPwrmgrWakeupRequestSourceFive, + /*domain_config=*/kDifPwrmgrDomainOptionCoreClockInLowPower | + kDifPwrmgrDomainOptionUsbClockInActivePower | + kDifPwrmgrDomainOptionMainPowerInLowPower); + // Enter low power mode. + LOG_INFO("Issue WFI to enter normal sleep"); + wait_for_interrupt(); + // data preserved + retention_sram_check((check_config_t){.do_write = false, .is_equal = true}); +} + +// test these 2 cases: +// deep sleep, no scrambling -> data preserved +// deep sleep, with scrambling -> data preserved +void enter_deep_sleep() { + // Prepare rstmgr for a reset. + rstmgr_testutils_pre_reset(&rstmgr); + // set up wakeup timer + aon_timer_testutils_wakeup_config(&aon_timer, 20); + // Deep sleep. + pwrmgr_testutils_enable_low_power(&pwrmgr, kDifPwrmgrWakeupRequestSourceFive, + 0); + + // Enter low power mode. + LOG_INFO("Issue WFI to enter deep sleep"); + wait_for_interrupt(); + CHECK(false, "Should have a reset to CPU before this line"); +} + +void set_up_reset_request(void) { + // Prepare rstmgr for a reset. + rstmgr_testutils_pre_reset(&rstmgr); + CHECK_DIF_OK(dif_pwrmgr_set_request_sources(&pwrmgr, kDifPwrmgrReqTypeReset, + kDifPwrmgrResetRequestSourceTwo, + kDifToggleEnabled)); + + CHECK_DIF_OK(dif_aon_timer_wakeup_stop(&aon_timer)); + + // Enter low power mode. + aon_timer_testutils_watchdog_config(&aon_timer, UINT32_MAX, 20, false); + LOG_INFO("wait for reset"); + wait_for_interrupt(); + CHECK(false, "Should have a reset to CPU and ret_sram before this line"); +} + +bool test_main(void) { + dif_sram_ctrl_t ret_sram; + + // Enable global and external IRQ at Ibex. + irq_global_ctrl(true); + irq_external_ctrl(true); + + mmio_region_t addr = mmio_region_from_addr(TOP_MATCHA_PWRMGR_AON_BASE_ADDR); + CHECK_DIF_OK(dif_pwrmgr_init(addr, &pwrmgr)); + addr = mmio_region_from_addr(TOP_MATCHA_RSTMGR_AON_BASE_ADDR); + CHECK_DIF_OK(dif_rstmgr_init(addr, &rstmgr)); + addr = mmio_region_from_addr(TOP_MATCHA_AON_TIMER_AON_BASE_ADDR); + CHECK_DIF_OK(dif_aon_timer_init(addr, &aon_timer)); + addr = mmio_region_from_addr(TOP_MATCHA_SRAM_CTRL_RET_AON_REGS_BASE_ADDR); + CHECK_DIF_OK(dif_sram_ctrl_init(addr, &ret_sram)); + addr = mmio_region_from_addr(TOP_MATCHA_RV_PLIC_BASE_ADDR); + CHECK_DIF_OK(dif_rv_plic_init(addr, &rv_plic)); + + dif_rstmgr_reset_info_bitfield_t rstmgr_reset_info; + rstmgr_reset_info = rstmgr_testutils_reason_get(); + + LOG_INFO("Reset info = %08x", rstmgr_reset_info); + + if (rstmgr_reset_info == kDifRstmgrResetInfoPor) { + LOG_INFO("POR reset"); + + test_ret_sram_in_normal_sleep(); + + enter_deep_sleep(); + } else if (rstmgr_reset_info & kDifRstmgrResetInfoLowPowerExit) { + // This branch will be entered twice. + // In the first time, ret_non_scrambled is True. In the 2nd time, it's + // false. + LOG_INFO("wake up from deep sleep with ret_non_scrambled: %x", + ret_non_scrambled); + + CHECK(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, + kDifPwrmgrWakeupRequestSourceFive)); + // data preserved + retention_sram_check((check_config_t){.do_write = false, .is_equal = true}); + + set_up_reset_request(); + } else if (rstmgr_reset_info & kDifRstmgrResetInfoWatchdog) { + // This branch will be entered twice. + // In the first time, ret_non_scrambled is True. In the 2nd time, it's + // false. + LOG_INFO("watchdog reset with ret_non_scrambled: %x", ret_non_scrambled); + if (ret_non_scrambled) { + // reset due to a reset request, no scrambling -> data preserved + retention_sram_check( + (check_config_t){.do_write = false, .is_equal = true}); + + LOG_INFO("Start to test ret_sram with scramble enabled"); + + dif_flash_ctrl_state_t flash_ctrl_state; + CHECK_DIF_OK(dif_flash_ctrl_init_state( + &flash_ctrl_state, + mmio_region_from_addr(TOP_MATCHA_FLASH_CTRL_CORE_BASE_ADDR))); + flash_ctrl_testutils_default_region_access(&flash_ctrl_state, + /*rd_en=*/true, + /*prog_en=*/true, + /*erase_en=*/true, + /*scramble_en=*/false, + /*ecc_en=*/false, + /*he_en=*/false); + // write ret_non_scrambled to 0 + const uint32_t new_data = 0; + CHECK(flash_ctrl_testutils_write(&flash_ctrl_state, + (uint32_t)&ret_non_scrambled - + TOP_MATCHA_FLASH_CTRL_MEM_BASE_ADDR, + /*partition_id*/ 0, &new_data, + kDifFlashCtrlPartitionTypeData, + /*word_count*/ 1), + "Flash write failed"); + // wipe data otherwise, the data may still be read after reset, since it's + // written with the default key/nounce. + LOG_INFO("Wiping ret_sram..."); + sram_ctrl_testutils_wipe(&ret_sram); + LOG_INFO("Scrambling ret_sram..."); + sram_ctrl_testutils_scramble(&ret_sram); + + test_ret_sram_in_normal_sleep(); + + enter_deep_sleep(); + } else { + // reset due to a reset request, with scrambling -> data NOT preserved + retention_sram_check( + (check_config_t){.do_write = false, .is_equal = false}); + } + } else { + LOG_FATAL("Unexepected reset type detected."); + } + + return true; +}