blob: c54c8180d4d66428650cde5cad23f43874f66040 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#include <assert.h>
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/flash_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/boot_data.h"
#include "sw/device/silicon_creator/lib/drivers/lifecycle.h"
#include "sw/device/silicon_creator/lib/drivers/rstmgr.h"
#include "sw/device/silicon_creator/lib/manifest_def.h"
#include "sw/device/silicon_creator/lib/test_main.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
OTTF_DEFINE_TEST_CONFIG();
enum {
kNewMinSecVer = 1,
kFlashCounterId = 0,
};
static void print_boot_data(const boot_data_t *boot_data) {
LOG_INFO("counter: %d, min_security_version_rom_ext: %d", boot_data->counter,
boot_data->min_security_version_rom_ext);
}
static void increment_flash_counter(void) {
dif_flash_ctrl_state_t flash_ctrl;
CHECK_DIF_OK(dif_flash_ctrl_init_state(
&flash_ctrl,
mmio_region_from_addr(TOP_EARLGREY_FLASH_CTRL_CORE_BASE_ADDR)));
flash_ctrl_testutils_default_region_access(&flash_ctrl,
/*rd_en*/ true,
/*prog_en*/ true, false, false,
false, false);
flash_ctrl_testutils_counter_increment(&flash_ctrl, kFlashCounterId);
flash_ctrl_testutils_default_region_access(&flash_ctrl, false, false, false,
false, false, false);
}
static rom_error_t first_boot_test(void) {
LOG_INFO("First boot: interrupted upgrade");
boot_data_t boot_data;
RETURN_IF_ERROR(boot_data_read(lifecycle_state_get(), &boot_data));
print_boot_data(&boot_data);
CHECK(boot_data.min_security_version_rom_ext == 0);
boot_data.min_security_version_rom_ext = kNewMinSecVer;
RETURN_IF_ERROR(boot_data_write(&boot_data));
RETURN_IF_ERROR(boot_data_read(lifecycle_state_get(), &boot_data));
print_boot_data(&boot_data);
CHECK(boot_data.min_security_version_rom_ext == kNewMinSecVer);
uint32_t corrupted_words[4] = {0};
flash_ctrl_info_perms_set(kFlashCtrlInfoPageBootData0,
(flash_ctrl_perms_t){
.read = kMultiBitBool4False,
.write = kMultiBitBool4True,
.erase = kMultiBitBool4False,
});
RETURN_IF_ERROR(flash_ctrl_info_write(kFlashCtrlInfoPageBootData0, 0, 4,
&corrupted_words));
flash_ctrl_info_perms_set(kFlashCtrlInfoPageBootData0,
(flash_ctrl_perms_t){
.read = kMultiBitBool4False,
.write = kMultiBitBool4False,
.erase = kMultiBitBool4False,
});
return kErrorOk;
}
static rom_error_t second_boot_test(void) {
LOG_INFO("Second boot: Recovery");
boot_data_t boot_data;
RETURN_IF_ERROR(boot_data_read(lifecycle_state_get(), &boot_data));
print_boot_data(&boot_data);
CHECK(boot_data.min_security_version_rom_ext == 0);
boot_data.min_security_version_rom_ext = kNewMinSecVer;
RETURN_IF_ERROR(boot_data_write(&boot_data));
RETURN_IF_ERROR(boot_data_read(lifecycle_state_get(), &boot_data));
print_boot_data(&boot_data);
CHECK(boot_data.min_security_version_rom_ext == kNewMinSecVer);
return kErrorOk;
}
static rom_error_t third_boot_test(void) {
LOG_INFO("Third boot: Done");
boot_data_t boot_data;
RETURN_IF_ERROR(boot_data_read(lifecycle_state_get(), &boot_data));
print_boot_data(&boot_data);
CHECK(boot_data.min_security_version_rom_ext == kNewMinSecVer);
return kErrorOk;
}
bool test_main(void) {
rom_error_t result = kErrorOk;
size_t reboot_counter = flash_ctrl_testutils_counter_get(kFlashCounterId);
switch (reboot_counter) {
case 0: {
const manifest_t *manifest = manifest_def_get();
LOG_INFO("Manifest security version: %d", manifest->security_version);
CHECK(manifest->security_version > kNewMinSecVer);
EXECUTE_TEST(result, first_boot_test);
increment_flash_counter();
rstmgr_reset();
return false;
}
case 1: {
EXECUTE_TEST(result, second_boot_test);
increment_flash_counter();
rstmgr_reset();
return false;
}
case 2: {
EXECUTE_TEST(result, third_boot_test);
return result == kErrorOk;
}
}
return false;
}