Merge "Add 3 pwrmgr tests to edacloud"
diff --git a/hw/top_matcha/dv/chip_sim_cfg.hjson b/hw/top_matcha/dv/chip_sim_cfg.hjson index be83664..4452cc6 100644 --- a/hw/top_matcha/dv/chip_sim_cfg.hjson +++ b/hw/top_matcha/dv/chip_sim_cfg.hjson
@@ -2175,7 +2175,6 @@ "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", @@ -2210,7 +2209,6 @@ "chip_sw_uart_smoketest", "chip_sw_uart_tx_rx", "chip_tap_straps_dev", - "chip_tap_straps_prod", "chip_tap_straps_rma", ] }
diff --git a/sw/device/tests/kelvin/fpga_tests/BUILD b/sw/device/tests/kelvin/fpga_tests/BUILD index 364d0cf..612828e 100644 --- a/sw/device/tests/kelvin/fpga_tests/BUILD +++ b/sw/device/tests/kelvin/fpga_tests/BUILD
@@ -23,11 +23,10 @@ "//hw/top_matcha/ip/ml_top/data:ml_top_regs", "//hw/top_matcha/sw/autogen:top_matcha", "//sw/device/lib:spi_flash", + "//sw/device/lib/dif:rv_plic_sec", "//sw/device/lib/dif:smc_ctrl", - "//sw/device/lib/testing/test_framework:ottf_start", - "//sw/device/lib/testing/test_framework:test_util", - "@lowrisc_opentitan//sw/device/lib/testing/test_framework:ottf_test_config", - "@lowrisc_opentitan//sw/device/silicon_creator/lib:manifest_def", + "//sw/device/lib/dif:tlul_mailbox", + "//sw/device/tests:test_lib", ], ) @@ -43,11 +42,13 @@ per_device_deps = { "fpga_nexus": [NEXUS_CORE_TARGETS.get("smc")], }, - var_name = "kelvin_test_smc_fpga_nexus_bin", deps = [ + "//hw/top_matcha/ip/ml_top/data:ml_top_regs", "//hw/top_matcha/sw/autogen:top_matcha", - "//sw/device/lib/testing/test_framework:ottf_start_smc", - "//sw/device/lib/testing/test_framework:test_util", - "@lowrisc_opentitan//sw/device/lib/testing/test_framework:ottf_test_config", + "//sw/device/lib/dif:ml_top", + "//sw/device/lib/dif:rv_plic_smc", + "//sw/device/lib/dif:tlul_mailbox", + "//sw/device/tests:test_lib_smc", + "@lowrisc_opentitan//sw/device/lib/dif:rv_timer", ], )
diff --git a/sw/device/tests/kelvin/fpga_tests/kelvin_test_sc.c b/sw/device/tests/kelvin/fpga_tests/kelvin_test_sc.c index 0031960..4887bd2 100644 --- a/sw/device/tests/kelvin/fpga_tests/kelvin_test_sc.c +++ b/sw/device/tests/kelvin/fpga_tests/kelvin_test_sc.c
@@ -3,8 +3,11 @@ #include "hw/top_matcha/ip/ml_top/data/ml_top_regs.h" // Generated. #include "hw/top_matcha/sw/autogen/top_matcha.h" #include "sw/device/lib/arch/device.h" +#include "sw/device/lib/dif/dif_rv_plic.h" #include "sw/device/lib/dif/dif_smc_ctrl.h" +#include "sw/device/lib/dif/dif_tlul_mailbox.h" #include "sw/device/lib/dif/dif_uart.h" +#include "sw/device/lib/runtime/irq.h" #include "sw/device/lib/runtime/print.h" #include "sw/device/lib/spi_flash.h" #include "sw/device/lib/testing/test_framework/check.h" @@ -13,16 +16,31 @@ #include "sw/device/lib/testing/test_framework/test_util.h" /* - * Sample program to run some code on all cores in the system. - * SC - Orchestrate the other cores, print status to UART. - * SMC - Print to UART. - * Kelvin - SW program built to run on Kelvin. + * SC - Initialize SMC, load kelvin program, and print status to UART. + * SMC - Print to UART and orchestrate ML core/programs. */ OTTF_DEFINE_TEST_CONFIG(); static dif_smc_ctrl_t smc_ctrl; static dif_uart_t uart; +static dif_rv_plic_t plic_sec; +static dif_tlul_mailbox_t tlul_mailbox; + +volatile uint32_t message; + +void ottf_external_isr(void) { + dif_rv_plic_irq_id_t plic_irq_id; + uint32_t rx; + CHECK_DIF_OK(dif_rv_plic_irq_claim(&plic_sec, kTopMatchaPlicTargetIbex0, + &plic_irq_id)); + CHECK_DIF_OK( + dif_tlul_mailbox_irq_acknowledge(&tlul_mailbox, kDifTlulMailboxIrqRtirq)); + CHECK_DIF_OK(dif_tlul_mailbox_read_message(&tlul_mailbox, &rx)); + message = rx; + CHECK_DIF_OK(dif_rv_plic_irq_complete(&plic_sec, kTopMatchaPlicTargetIbex0, + plic_irq_id)); +} void _ottf_main(void) { test_status_set(kTestStatusInTest); @@ -44,17 +62,33 @@ mmio_region_write32(ml_dmem, i * sizeof(uint32_t), 0); } + // Setup mailbox. + CHECK_DIF_OK(dif_tlul_mailbox_init( + mmio_region_from_addr(TOP_MATCHA_TLUL_MAILBOX_SEC_BASE_ADDR), + &tlul_mailbox)); + CHECK_DIF_OK(dif_tlul_mailbox_irq_set_enabled( + &tlul_mailbox, kDifTlulMailboxIrqRtirq, kDifToggleEnabled)); + CHECK_DIF_OK(dif_tlul_mailbox_irq_set_enabled( + &tlul_mailbox, kDifTlulMailboxIrqWtirq, kDifToggleEnabled)); + CHECK_DIF_OK(dif_tlul_mailbox_irq_set_enabled( + &tlul_mailbox, kDifTlulMailboxIrqEirq, kDifToggleEnabled)); + + // Set Interrupt. + CHECK_DIF_OK(dif_rv_plic_init( + mmio_region_from_addr(TOP_MATCHA_RV_PLIC_BASE_ADDR), &plic_sec)); + CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( + &plic_sec, kTopMatchaPlicIrqIdTlulMailboxSecRtirq, + kTopMatchaPlicTargetIbex0, kDifToggleEnabled)); + CHECK_DIF_OK(dif_rv_plic_irq_set_priority( + &plic_sec, kTopMatchaPlicIrqIdTlulMailboxSecRtirq, 1)); + irq_global_ctrl(true); + irq_external_ctrl(true); + // Enable SMC. CHECK_DIF_OK(dif_smc_ctrl_init( mmio_region_from_addr(TOP_MATCHA_SMC_CTRL_BASE_ADDR), &smc_ctrl)); CHECK_DIF_OK(dif_smc_ctrl_set_en(&smc_ctrl)); - // Reset and Freeze Kelvin. - mmio_region_t base_addr = - mmio_region_from_addr(TOP_MATCHA_ML_TOP_CORE_BASE_ADDR); - mmio_region_write32(base_addr, ML_TOP_CTRL_REG_OFFSET, - ML_TOP_CTRL_REG_RESVAL | (1 << ML_TOP_CTRL_FREEZE_BIT)); - // Copy binary to ML_DMEM. char kelvin_bin_name[256] = {'\0'}; size_t bin_offset = 0; @@ -70,32 +104,15 @@ CHECK_DIF_OK(kelvin_load_result, "Failed to load %s", kelvin_bin_name); test_num++; LOG_INFO("Test %d: Run kelvin binary %s", test_num, kelvin_bin_name); - // Start up Kelvin. - mmio_region_write32(base_addr, ML_TOP_CTRL_REG_OFFSET, 0x0); - uint32_t intr_state = - mmio_region_read32(base_addr, ML_TOP_INTR_STATE_REG_OFFSET); - // TODO(ykwang): Change this to interrupt handler. - while (intr_state == 0x0) { - busy_spin_micros(10 * 1000); // Wait for 10ms. - intr_state = mmio_region_read32(base_addr, ML_TOP_INTR_STATE_REG_OFFSET); - } - // Received interrupts from Kelvin core, check if only FINISH asserted - if (intr_state != (1 << ML_TOP_INTR_STATE_FINISH_BIT)) { - LOG_ERROR("INTR_STATE read out: expected : 0x%x | actual: 0x%x", - (1 << ML_TOP_INTR_STATE_FINISH_BIT), intr_state); + uint32_t tx = 0; + // Send to smc to kickoff ML program + CHECK_DIF_OK(dif_tlul_mailbox_send_message(&tlul_mailbox, &tx)); + // Wait for mailbox interrupt + asm volatile("wfi"); + if (message != (1 << ML_TOP_INTR_STATE_FINISH_BIT)) { + LOG_ERROR(" Test finish with fault"); failed_test++; } - // Reset and halt Kelvin - mmio_region_write32(base_addr, ML_TOP_CTRL_REG_OFFSET, - ML_TOP_CTRL_REG_RESVAL | (1 << ML_TOP_CTRL_FREEZE_BIT)); - // Write 1 to clear INTR_STATE - mmio_region_write32(base_addr, ML_TOP_INTR_STATE_REG_OFFSET, intr_state); - intr_state = mmio_region_read32(base_addr, ML_TOP_INTR_STATE_REG_OFFSET); - CHECK( - intr_state == 0, - "ML_TOP_Core offset 0 INTR_STATE read again - Expected: 0 | Actual: " - "0x%x", - intr_state); } LOG_INFO("Total test: %d, failed test: %d", test_num, failed_test); if (failed_test == 0) {
diff --git a/sw/device/tests/kelvin/fpga_tests/kelvin_test_smc.c b/sw/device/tests/kelvin/fpga_tests/kelvin_test_smc.c index ec9f4a8..916b4c8 100644 --- a/sw/device/tests/kelvin/fpga_tests/kelvin_test_smc.c +++ b/sw/device/tests/kelvin/fpga_tests/kelvin_test_smc.c
@@ -1,17 +1,167 @@ +#include "hw/top_matcha/ip/ml_top/data/ml_top_regs.h" // Generated. #include "hw/top_matcha/sw/autogen/top_matcha.h" #include "sw/device/lib/arch/device.h" +#include "sw/device/lib/dif/dif_ml_top.h" +#include "sw/device/lib/dif/dif_rv_plic.h" +#include "sw/device/lib/dif/dif_rv_timer.h" +#include "sw/device/lib/dif/dif_tlul_mailbox.h" #include "sw/device/lib/dif/dif_uart.h" +#include "sw/device/lib/runtime/irq.h" #include "sw/device/lib/runtime/print.h" #include "sw/device/lib/testing/test_framework/check.h" #include "sw/device/lib/testing/test_framework/ottf_test_config.h" #include "sw/device/lib/testing/test_framework/test_util.h" +/* + * Sample program to run some code on all cores in the system. + * SMC - Print to UART and orchestrate ML core/programs. + * Kelvin - SW program built to run on Kelvin. + */ + OTTF_DEFINE_TEST_CONFIG(); static dif_uart_t smc_uart; +static dif_tlul_mailbox_t tlul_mailbox; +static dif_rv_plic_t plic_smc; +static dif_rv_timer_t rv_timer; +static dif_ml_top_t ml_top; + +static volatile bool ml_top_done = false; +static volatile bool bin_loaded = false; +static volatile uint32_t ml_result = 0; + +void ottf_external_isr(void) { + dif_rv_plic_irq_id_t plic_irq_id; + CHECK_DIF_OK(dif_rv_plic_irq_claim(&plic_smc, kTopMatchaPlicTargetIbex0Smc, + &plic_irq_id)); + top_matcha_plic_peripheral_smc_t peripheral_id = + top_matcha_plic_interrupt_for_peripheral_smc[plic_irq_id]; + CHECK(peripheral_id == kTopMatchaPlicPeripheralTlulMailboxSmc || + peripheral_id == kTopMatchaPlicPeripheralMlTop, + "Unexpected peripheral in ISR: %d", peripheral_id); + switch (peripheral_id) { + case kTopMatchaPlicPeripheralTlulMailboxSmc: { + uint32_t rx; + CHECK_DIF_OK(dif_tlul_mailbox_irq_acknowledge(&tlul_mailbox, + kDifTlulMailboxIrqRtirq)); + CHECK_DIF_OK(dif_tlul_mailbox_read_message(&tlul_mailbox, &rx)); + bin_loaded = true; + break; + } + case kTopMatchaPlicPeripheralMlTop: { + mmio_region_t base_addr = + mmio_region_from_addr(TOP_MATCHA_ML_TOP_CORE_BASE_ADDR); + // Reset and halt Kelvin + mmio_region_write32( + base_addr, ML_TOP_CTRL_REG_OFFSET, + ML_TOP_CTRL_REG_RESVAL | (1 << ML_TOP_CTRL_FREEZE_BIT)); + ml_result = mmio_region_read32(base_addr, ML_TOP_INTR_STATE_REG_OFFSET); + // Write 1 to clear INTR_STATE + mmio_region_write32(base_addr, ML_TOP_INTR_STATE_REG_OFFSET, ml_result); + uint32_t intr_state = + mmio_region_read32(base_addr, ML_TOP_INTR_STATE_REG_OFFSET); + CHECK(intr_state == 0, + "ML Top interrupt reset failed: expect 0, actual 0x%x", intr_state); + ml_top_done = true; + break; + } + default: + LOG_FATAL("Peripheral is not implemented!"); + } + CHECK_DIF_OK(dif_rv_plic_irq_complete(&plic_smc, kTopMatchaPlicTargetIbex0Smc, + plic_irq_id)); +} + +/* + * Configures all the relevant interrupts in PLIC_SMC. + */ +static void plic_smc_configure_irqs(dif_rv_plic_t *plic) { + // Set ML_TOP IRQ priorities to MAX + CHECK_DIF_OK(dif_rv_plic_irq_set_priority( + plic, kTopMatchaPlicIrqIdMlTopFinish, kDifRvPlicMaxPriority)); + CHECK_DIF_OK(dif_rv_plic_irq_set_priority(plic, kTopMatchaPlicIrqIdMlTopFault, + kDifRvPlicMaxPriority)); + // Set Ibex IRQ priority threshold level + CHECK_DIF_OK(dif_rv_plic_target_set_threshold( + plic, kTopMatchaPlicTargetIbex0Smc, kDifRvPlicMinPriority)); + + // Enable Mailbox IRQs + CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( + plic, kTopMatchaPlicIrqIdTlulMailboxSmcRtirq, + kTopMatchaPlicTargetIbex0Smc, kDifToggleEnabled)); + CHECK_DIF_OK(dif_rv_plic_irq_set_priority( + plic, kTopMatchaPlicIrqIdTlulMailboxSmcRtirq, 1)); + // Enable ML core IRQs + CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(plic, kTopMatchaPlicIrqIdMlTopFinish, + kTopMatchaPlicTargetIbex0Smc, + kDifToggleEnabled)); + CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(plic, kTopMatchaPlicIrqIdMlTopFault, + kTopMatchaPlicTargetIbex0Smc, + kDifToggleEnabled)); +} void _ottf_main(void) { init_uart(TOP_MATCHA_SMC_UART_BASE_ADDR, &smc_uart); LOG_INFO("kelvin_test_smc"); - asm volatile("wfi"); + + // Configure Mailbox. + CHECK_DIF_OK(dif_tlul_mailbox_init( + mmio_region_from_addr(TOP_MATCHA_TLUL_MAILBOX_SMC_BASE_ADDR), + &tlul_mailbox)); + CHECK_DIF_OK(dif_tlul_mailbox_irq_set_enabled( + &tlul_mailbox, kDifTlulMailboxIrqRtirq, kDifToggleEnabled)); + CHECK_DIF_OK(dif_tlul_mailbox_irq_set_enabled( + &tlul_mailbox, kDifTlulMailboxIrqWtirq, kDifToggleEnabled)); + CHECK_DIF_OK(dif_tlul_mailbox_irq_set_enabled( + &tlul_mailbox, kDifTlulMailboxIrqEirq, kDifToggleEnabled)); + + // Init ML_TOP + CHECK_DIF_OK(dif_ml_top_init( + mmio_region_from_addr(TOP_MATCHA_ML_TOP_CORE_BASE_ADDR), &ml_top)); + CHECK_DIF_OK(dif_ml_top_irq_set_enabled(&ml_top, kDifMlTopIrqFinish, + kDifToggleEnabled)); + CHECK_DIF_OK(dif_ml_top_irq_set_enabled(&ml_top, kDifMlTopIrqFault, + kDifToggleEnabled)); + dif_ml_top_reset_ctrl_en(&ml_top); + + // Set interrupt. + CHECK_DIF_OK(dif_rv_plic_init( + mmio_region_from_addr(TOP_MATCHA_RV_PLIC_SMC_BASE_ADDR), &plic_smc)); + plic_smc_configure_irqs(&plic_smc); + irq_global_ctrl(true); + irq_external_ctrl(true); + + // Set timer. + dif_rv_timer_tick_params_t tick_params; + CHECK_DIF_OK(dif_rv_timer_init( + mmio_region_from_addr(TOP_MATCHA_RV_TIMER_SMC_BASE_ADDR), &rv_timer)); + CHECK_DIF_OK(dif_rv_timer_approximate_tick_params(kClockFreqPeripheralHz, + 1000, &tick_params)); + CHECK_DIF_OK(dif_rv_timer_set_tick_params(&rv_timer, 0, tick_params)); + CHECK_DIF_OK( + dif_rv_timer_counter_set_enabled(&rv_timer, 0, kDifToggleEnabled)); + + uint32_t bin_index = 0; + while (true) { + uint64_t timer_start, timer_end; + bin_loaded = false; + while (!bin_loaded) { + asm volatile("wfi"); + } + // Start up Kelvin. + ml_top_done = false; + ml_result = 0; + CHECK_DIF_OK(dif_rv_timer_counter_read(&rv_timer, 0, &timer_start)); + mmio_region_t base_addr = + mmio_region_from_addr(TOP_MATCHA_ML_TOP_CORE_BASE_ADDR); + mmio_region_write32(base_addr, ML_TOP_CTRL_REG_OFFSET, 0x0); + while (!ml_top_done) { + asm volatile("wfi"); + } + CHECK_DIF_OK(dif_rv_timer_counter_read(&rv_timer, 0, &timer_end)); + LOG_INFO("Test %d: Finish in %d ms", ++bin_index, + (uint32_t)(timer_end - timer_start)); + uint32_t tx = ml_result; + CHECK_DIF_OK(dif_tlul_mailbox_send_message(&tlul_mailbox, &tx)); + } }