diff --git a/sw/device/lib/testing/flash_ctrl_testutils.c b/sw/device/lib/testing/flash_ctrl_testutils.c index c19bfdef4b3f9..e27e28c6cff95 100644 --- a/sw/device/lib/testing/flash_ctrl_testutils.c +++ b/sw/device/lib/testing/flash_ctrl_testutils.c @@ -392,3 +392,19 @@ void flash_ctrl_testutils_info_region_print( mubi_prop(p->ecc_en, "EC"), mubi_prop(p->high_endurance_en, "HE"), locked ? "LK" : "UN"); } + +status_t flash_ctrl_testutils_find_unlocked_region( + dif_flash_ctrl_state_t *flash, uint32_t start, uint32_t end, + uint32_t *region) { + for (uint32_t data_region = start; data_region <= end; data_region++) { + bool locked; + CHECK_DIF_OK( + dif_flash_ctrl_data_region_is_locked(flash, data_region, &locked)); + if (!locked) { + LOG_INFO("Region %u is unlocked", data_region); + *region = data_region; + return OK_STATUS(); + } + } + return INTERNAL(); +} diff --git a/sw/device/lib/testing/flash_ctrl_testutils.h b/sw/device/lib/testing/flash_ctrl_testutils.h index eca15bc1a015c..fb7c2bc138827 100644 --- a/sw/device/lib/testing/flash_ctrl_testutils.h +++ b/sw/device/lib/testing/flash_ctrl_testutils.h @@ -314,4 +314,18 @@ void flash_ctrl_testutils_data_region_print( void flash_ctrl_testutils_info_region_print( dif_flash_ctrl_info_region_t region, dif_flash_ctrl_region_properties_t *p, bool locked); + +/** + * Check for unlocked flash data regions + * + * This prints the unlocked region that is found + * + * @param flash A flash_ctrl state handle. + * @param start Start of the region range to search + * @param end End of the region range to search + * @param region The data protection region + */ +status_t flash_ctrl_testutils_find_unlocked_region( + dif_flash_ctrl_state_t *flash, uint32_t start, uint32_t end, + uint32_t *region); #endif // OPENTITAN_SW_DEVICE_LIB_TESTING_FLASH_CTRL_TESTUTILS_H_ diff --git a/sw/device/tests/flash_ctrl_idle_low_power_test.c b/sw/device/tests/flash_ctrl_idle_low_power_test.c index 0b74469bd9a77..0db0d13110921 100644 --- a/sw/device/tests/flash_ctrl_idle_low_power_test.c +++ b/sw/device/tests/flash_ctrl_idle_low_power_test.c @@ -18,11 +18,11 @@ #include "sw/device/lib/testing/test_framework/check.h" #include "sw/device/lib/testing/test_framework/ottf_main.h" +#include "flash_ctrl_regs.h" #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" #include "sw/device/lib/testing/autogen/isr_testutils.h" OTTF_DEFINE_TEST_CONFIG(); - static dif_rv_plic_t plic; static dif_aon_timer_t aon; static dif_rv_core_ibex_t rv_core_ibex; @@ -43,7 +43,7 @@ static top_earlgrey_plic_peripheral_t peripheral_serviced; static dif_aon_timer_irq_t irq_serviced; enum { - kFlashDataRegion = 2, // The ROM_EXT protects itself using regions 0-1. + kDataRegions = FLASH_CTRL_PARAM_NUM_REGIONS, kRegionBasePageIndex = 256 + 32, // First non-ROM_EXT page in bank 1 (avoids program code.) kPartitionId = 0, @@ -102,6 +102,8 @@ bool test_main(void) { dif_pwrmgr_t pwrmgr; dif_rstmgr_t rstmgr; + uint32_t flash_region_index; + CHECK_DIF_OK(dif_rv_plic_init( mmio_region_from_addr(TOP_EARLGREY_RV_PLIC_BASE_ADDR), &plic)); CHECK_DIF_OK(dif_flash_ctrl_init_state( @@ -126,8 +128,13 @@ bool test_main(void) { rstmgr_reset_info = rstmgr_testutils_reason_get(); uint32_t address = 0; + // Find the first unlocked flash region and use that for testing + + CHECK_STATUS_OK(flash_ctrl_testutils_find_unlocked_region( + &flash, 0, kDataRegions - 1, &flash_region_index)); + CHECK_STATUS_OK(flash_ctrl_testutils_data_region_setup( - &flash, kRegionBasePageIndex, kFlashDataRegion, kRegionSize, &address)); + &flash, kRegionBasePageIndex, flash_region_index, kRegionSize, &address)); if (rstmgr_reset_info == kDifRstmgrResetInfoPor) { // Create data. Random data will be different than diff --git a/sw/device/tests/flash_ctrl_ops_test.c b/sw/device/tests/flash_ctrl_ops_test.c index d421aa0ccc1aa..a94a70b559ceb 100644 --- a/sw/device/tests/flash_ctrl_ops_test.c +++ b/sw/device/tests/flash_ctrl_ops_test.c @@ -14,6 +14,7 @@ #include "sw/device/lib/testing/test_framework/check.h" #include "sw/device/lib/testing/test_framework/ottf_main.h" +#include "flash_ctrl_regs.h" #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" #include "otp_ctrl_regs.h" #include "sw/device/lib/testing/autogen/isr_testutils.h" @@ -68,6 +69,7 @@ enum { kInfoSize = 16, kDataSize = 32, kPageSize = 2048, + kDataRegions = FLASH_CTRL_PARAM_NUM_REGIONS }; const uint32_t kRandomData1[kInfoSize] = { @@ -266,6 +268,8 @@ static void do_bank0_data_partition_test(void) { .prog_en = kMultiBitBool4True, .rd_en = kMultiBitBool4True}; + CHECK_STATUS_OK(flash_ctrl_testutils_find_unlocked_region( + &flash_state, 0, kDataRegions - 1, &flash_bank_0_data_region)); CHECK_STATUS_OK(flash_ctrl_testutils_data_region_setup_properties( &flash_state, kRegionBaseBank0Page0Index, flash_bank_0_data_region, kRegionSize, region_properties, &address)); @@ -309,6 +313,8 @@ static void do_bank1_data_partition_test(void) { uint32_t page_index = (i == 0) ? flash_bank_1_page_index : flash_bank_1_page_index_scr; const uint32_t *test_data = (i == 0) ? kRandomData4 : kRandomData5; + CHECK_STATUS_OK(flash_ctrl_testutils_find_unlocked_region( + &flash_state, 0, kDataRegions - 1, &flash_bank_1_data_region)); if (i == 0) { // Set region1 for non-scrambled ecc enabled. @@ -316,6 +322,10 @@ static void do_bank1_data_partition_test(void) { &flash_state, page_index, flash_bank_1_data_region, kRegionSize, &address)); } else { + CHECK_STATUS_OK(flash_ctrl_testutils_find_unlocked_region( + &flash_state, flash_bank_1_data_region + 1, kDataRegions - 1, + &flash_bank_1_data_region_scr)); + // Set region2 for scrambled ecc enabled. CHECK_STATUS_OK(flash_ctrl_testutils_data_region_scrambled_setup( &flash_state, page_index, flash_bank_1_data_region_scr, kRegionSize, @@ -423,22 +433,9 @@ static void do_bank1_data_partition_test(void) { bool test_main(void) { flash_info = dif_flash_ctrl_get_device_info(); - // Determine the region index and page index to use for tests. - // Test data page used for flash bank 1 should be the lowest and highest - // usable page. - if (kBootStage != kBootStageOwner) { - flash_bank_0_data_region = 0; - flash_bank_1_page_index = flash_info.data_pages; - } else { - // If we boot up in owner stage, the first 2 regions will be used by - // ROM_EXT. - flash_bank_0_data_region = 2; - // First 0x20 pages are configured by ROM_EXT. To avoid conflicts, skip over - // these pages. - flash_bank_1_page_index = flash_info.data_pages + 0x20; - } - flash_bank_1_data_region = flash_bank_0_data_region + 1; - flash_bank_1_data_region_scr = flash_bank_0_data_region + 2; + // First 0x20 pages are configured by ROM_EXT. To avoid conflicts, skip over + // these pages. + flash_bank_1_page_index = flash_info.data_pages + 0x20; flash_bank_1_page_index_scr = flash_info.data_pages * 2 - 1; CHECK_DIF_OK(dif_rv_plic_init( diff --git a/sw/device/tests/flash_ctrl_write_clear_test.c b/sw/device/tests/flash_ctrl_write_clear_test.c index 558b0e2edeae6..07501385960b9 100644 --- a/sw/device/tests/flash_ctrl_write_clear_test.c +++ b/sw/device/tests/flash_ctrl_write_clear_test.c @@ -39,8 +39,7 @@ enum { // partition in bank 1, otherwise known as owner partition B. kBank1StartPageNum = 256 + kRomExtPageCount, - // The ROM_EXT protects itself using regions 0-1. - kFlashRegionNum = 2, + kDataRegions = FLASH_CTRL_PARAM_NUM_REGIONS, }; @@ -93,7 +92,6 @@ static void flash_ctrl_write_clear_test( const uint64_t kExpectedValues[] = { UINT64_MAX, UINT64_MAX - 1, 0, 0xa5a5a5a594949494, 0xaaaaaaaaaaaaaaaa, }; - for (size_t i = 0; i < ARRAYSIZE(kExpectedValues); ++i) { flash_word_write_verify(start_addr + sizeof(uint64_t) * i, kExpectedValues[i]); @@ -102,9 +100,16 @@ static void flash_ctrl_write_clear_test( } bool test_main(void) { + uint32_t flash_region_index; + CHECK_DIF_OK(dif_flash_ctrl_init_state( &flash, mmio_region_from_addr(TOP_EARLGREY_FLASH_CTRL_CORE_BASE_ADDR))); + // Find the first unlocked flash region and use that for testing + + CHECK_STATUS_OK(flash_ctrl_testutils_find_unlocked_region( + &flash, 0, kDataRegions - 1, &flash_region_index)); + // The ROM_EXT configures the default region access. We can't modify the // values after configured. if (kBootStage != kBootStageOwner) { @@ -114,7 +119,7 @@ bool test_main(void) { } LOG_INFO("ECC enabled with high endurance disabled."); - flash_ctrl_write_clear_test(/*mp_region_index=*/kFlashRegionNum, + flash_ctrl_write_clear_test(/*mp_region_index=*/flash_region_index, (dif_flash_ctrl_data_region_properties_t){ .base = kBank1StartPageNum, .size = 1, @@ -128,7 +133,7 @@ bool test_main(void) { }}); LOG_INFO("ECC enabled with high endurance enabled."); - flash_ctrl_write_clear_test(/*mp_region_index=*/kFlashRegionNum, + flash_ctrl_write_clear_test(/*mp_region_index=*/flash_region_index, (dif_flash_ctrl_data_region_properties_t){ .base = kBank1StartPageNum + 1, .size = 1, diff --git a/sw/device/tests/rv_core_ibex_mem_test.c b/sw/device/tests/rv_core_ibex_mem_test.c index c1e322ba13708..53c67e195e99c 100644 --- a/sw/device/tests/rv_core_ibex_mem_test.c +++ b/sw/device/tests/rv_core_ibex_mem_test.c @@ -60,10 +60,10 @@ enum { kFlashTestLoc = TOP_EARLGREY_FLASH_CTRL_MEM_BASE_ADDR + kBank1StartPageNum * kFlashBytesPerPage, - // The ROM_EXT protects itself using regions 0-1. - kFlashRegionNum = 2, }; +static uint32_t flash_region_index; + // The flash test location is set to the encoding of `jalr x0, 0(x1)` // so execution can be tested. const uint32_t kFlashTestLocContent = 0x00008067; @@ -164,10 +164,14 @@ static void setup_flash(void) { dif_flash_ctrl_data_region_properties_t data_region = { .base = kBank1StartPageNum, .size = 0x1, .properties = region_properties}; + // Find the first unlocked flash region and use that for testing + CHECK_STATUS_OK(flash_ctrl_testutils_find_unlocked_region( + &flash_ctrl, 0, FLASH_CTRL_PARAM_NUM_REGIONS - 1, &flash_region_index)); + CHECK_DIF_OK(dif_flash_ctrl_set_data_region_properties( - &flash_ctrl, kFlashRegionNum, data_region)); + &flash_ctrl, flash_region_index, data_region)); CHECK_DIF_OK(dif_flash_ctrl_set_data_region_enablement( - &flash_ctrl, kFlashRegionNum, kDifToggleEnabled)); + &flash_ctrl, flash_region_index, kDifToggleEnabled)); // Make flash executable CHECK_DIF_OK(