Handle unsupported flash during POR processing.
If host flash initialization fails with errors that indicates the flash is not compatible with the FW, bail from POR processing and mark the flash as unsupported. The system will be allowed to boot in bypass mode in this case, and can never be activated.
This commit is contained in:
Родитель
80d334fe13
Коммит
4b8a3fce0d
|
@ -115,7 +115,8 @@ static int bmc_recovery_on_host_cs1 (struct bmc_recovery *recovery, struct hash_
|
||||||
else {
|
else {
|
||||||
if ((recovery->num_wdt < recovery->rec_ctrl.max_wdt) ||
|
if ((recovery->num_wdt < recovery->rec_ctrl.max_wdt) ||
|
||||||
(recovery->rec_ctrl.max_wdt == 0)) {
|
(recovery->rec_ctrl.max_wdt == 0)) {
|
||||||
status = recovery->host->flash_rollback (recovery->host, hash, rsa, false, false);
|
status = recovery->host->flash_rollback (recovery->host, hash, rsa, false,
|
||||||
|
false);
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
recovery->state = BMC_RECOVERY_STATE_ROLLBACK_DONE;
|
recovery->state = BMC_RECOVERY_STATE_ROLLBACK_DONE;
|
||||||
}
|
}
|
||||||
|
@ -146,7 +147,7 @@ static int bmc_recovery_on_host_cs1 (struct bmc_recovery *recovery, struct hash_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -159,7 +160,7 @@ static int bmc_recovery_on_host_cs1 (struct bmc_recovery *recovery, struct hash_
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
|
@ -31,6 +31,15 @@ static int host_processor_dual_initial_rot_flash_access (struct host_processor_d
|
||||||
do {
|
do {
|
||||||
retries++;
|
retries++;
|
||||||
status = host->flash->set_flash_for_rot_access (host->flash, host->control);
|
status = host->flash->set_flash_for_rot_access (host->flash, host->control);
|
||||||
|
if ((status == SPI_FLASH_UNSUPPORTED_DEVICE) ||
|
||||||
|
(status == SPI_FLASH_INCOMPATIBLE_SPI_MASTER) || (status == SPI_FLASH_NO_DEVICE) ||
|
||||||
|
(status == SPI_FLASH_NO_4BYTE_CMDS) || (status == SPI_FLASH_SFDP_LARGE_DEVICE) ||
|
||||||
|
(status == SPI_FLASH_SFDP_4BYTE_INCOMPATIBLE) ||
|
||||||
|
(status == SPI_FLASH_SFDP_QUAD_ENABLE_UNKNOWN)) {
|
||||||
|
host_state_manager_set_unsupported_flash (host->state, true);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
if (status != log_status) {
|
if (status != log_status) {
|
||||||
debug_log_create_entry (DEBUG_LOG_SEVERITY_ERROR, DEBUG_LOG_COMPONENT_HOST_FW,
|
debug_log_create_entry (DEBUG_LOG_SEVERITY_ERROR, DEBUG_LOG_COMPONENT_HOST_FW,
|
||||||
HOST_LOGGING_ROT_FLASH_ACCESS_ERROR, host->base.port, status);
|
HOST_LOGGING_ROT_FLASH_ACCESS_ERROR, host->base.port, status);
|
||||||
|
|
|
@ -6848,6 +6848,232 @@ static void host_processor_dual_test_power_on_reset_rot_access_error (CuTest *te
|
||||||
host_processor_dual_testing_validate_and_release (test, &host);
|
host_processor_dual_testing_validate_and_release (test, &host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void host_processor_dual_test_power_on_reset_rot_access_unsupported_device (CuTest *test)
|
||||||
|
{
|
||||||
|
struct host_processor_dual_testing host;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
TEST_START;
|
||||||
|
|
||||||
|
host_processor_dual_testing_init (test, &host);
|
||||||
|
|
||||||
|
status = mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_rot_access,
|
||||||
|
&host.flash_mgr, SPI_FLASH_UNSUPPORTED_DEVICE, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
status |= mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_host_access,
|
||||||
|
&host.flash_mgr, 0, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
CuAssertIntEquals (test, 0, status);
|
||||||
|
|
||||||
|
status = host.test.base.power_on_reset (&host.test.base, &host.hash.base, &host.rsa.base);
|
||||||
|
CuAssertIntEquals (test, SPI_FLASH_UNSUPPORTED_DEVICE, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_pfm_dirty (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, true, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_bypass_mode (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_flash_supported (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
host_processor_dual_testing_validate_and_release (test, &host);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void host_processor_dual_test_power_on_reset_rot_access_incompatible_spi_master (
|
||||||
|
CuTest *test)
|
||||||
|
{
|
||||||
|
struct host_processor_dual_testing host;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
TEST_START;
|
||||||
|
|
||||||
|
host_processor_dual_testing_init (test, &host);
|
||||||
|
|
||||||
|
status = mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_rot_access,
|
||||||
|
&host.flash_mgr, SPI_FLASH_INCOMPATIBLE_SPI_MASTER, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
status |= mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_host_access,
|
||||||
|
&host.flash_mgr, 0, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
CuAssertIntEquals (test, 0, status);
|
||||||
|
|
||||||
|
status = host.test.base.power_on_reset (&host.test.base, &host.hash.base, &host.rsa.base);
|
||||||
|
CuAssertIntEquals (test, SPI_FLASH_INCOMPATIBLE_SPI_MASTER, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_pfm_dirty (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, true, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_bypass_mode (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_flash_supported (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
host_processor_dual_testing_validate_and_release (test, &host);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void host_processor_dual_test_power_on_reset_rot_access_no_device (CuTest *test)
|
||||||
|
{
|
||||||
|
struct host_processor_dual_testing host;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
TEST_START;
|
||||||
|
|
||||||
|
host_processor_dual_testing_init (test, &host);
|
||||||
|
|
||||||
|
status = mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_rot_access,
|
||||||
|
&host.flash_mgr, SPI_FLASH_NO_DEVICE, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
status |= mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_host_access,
|
||||||
|
&host.flash_mgr, 0, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
CuAssertIntEquals (test, 0, status);
|
||||||
|
|
||||||
|
status = host.test.base.power_on_reset (&host.test.base, &host.hash.base, &host.rsa.base);
|
||||||
|
CuAssertIntEquals (test, SPI_FLASH_NO_DEVICE, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_pfm_dirty (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, true, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_bypass_mode (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_flash_supported (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
host_processor_dual_testing_validate_and_release (test, &host);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void host_processor_dual_test_power_on_reset_rot_access_no_4byte_addr_commands (CuTest *test)
|
||||||
|
{
|
||||||
|
struct host_processor_dual_testing host;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
TEST_START;
|
||||||
|
|
||||||
|
host_processor_dual_testing_init (test, &host);
|
||||||
|
|
||||||
|
status = mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_rot_access,
|
||||||
|
&host.flash_mgr, SPI_FLASH_NO_4BYTE_CMDS, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
status |= mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_host_access,
|
||||||
|
&host.flash_mgr, 0, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
CuAssertIntEquals (test, 0, status);
|
||||||
|
|
||||||
|
status = host.test.base.power_on_reset (&host.test.base, &host.hash.base, &host.rsa.base);
|
||||||
|
CuAssertIntEquals (test, SPI_FLASH_NO_4BYTE_CMDS, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_pfm_dirty (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, true, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_bypass_mode (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_flash_supported (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
host_processor_dual_testing_validate_and_release (test, &host);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void host_processor_dual_test_power_on_reset_rot_access_4byte_addr_incompatible (
|
||||||
|
CuTest *test)
|
||||||
|
{
|
||||||
|
struct host_processor_dual_testing host;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
TEST_START;
|
||||||
|
|
||||||
|
host_processor_dual_testing_init (test, &host);
|
||||||
|
|
||||||
|
status = mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_rot_access,
|
||||||
|
&host.flash_mgr, SPI_FLASH_SFDP_4BYTE_INCOMPATIBLE, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
status |= mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_host_access,
|
||||||
|
&host.flash_mgr, 0, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
CuAssertIntEquals (test, 0, status);
|
||||||
|
|
||||||
|
status = host.test.base.power_on_reset (&host.test.base, &host.hash.base, &host.rsa.base);
|
||||||
|
CuAssertIntEquals (test, SPI_FLASH_SFDP_4BYTE_INCOMPATIBLE, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_pfm_dirty (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, true, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_bypass_mode (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_flash_supported (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
host_processor_dual_testing_validate_and_release (test, &host);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void host_processor_dual_test_power_on_reset_rot_access_unknown_quad_enable (CuTest *test)
|
||||||
|
{
|
||||||
|
struct host_processor_dual_testing host;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
TEST_START;
|
||||||
|
|
||||||
|
host_processor_dual_testing_init (test, &host);
|
||||||
|
|
||||||
|
status = mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_rot_access,
|
||||||
|
&host.flash_mgr, SPI_FLASH_SFDP_QUAD_ENABLE_UNKNOWN, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
status |= mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_host_access,
|
||||||
|
&host.flash_mgr, 0, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
CuAssertIntEquals (test, 0, status);
|
||||||
|
|
||||||
|
status = host.test.base.power_on_reset (&host.test.base, &host.hash.base, &host.rsa.base);
|
||||||
|
CuAssertIntEquals (test, SPI_FLASH_SFDP_QUAD_ENABLE_UNKNOWN, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_pfm_dirty (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, true, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_bypass_mode (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_flash_supported (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
host_processor_dual_testing_validate_and_release (test, &host);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void host_processor_dual_test_power_on_reset_rot_access_large_device (CuTest *test)
|
||||||
|
{
|
||||||
|
struct host_processor_dual_testing host;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
TEST_START;
|
||||||
|
|
||||||
|
host_processor_dual_testing_init (test, &host);
|
||||||
|
|
||||||
|
status = mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_rot_access,
|
||||||
|
&host.flash_mgr, SPI_FLASH_SFDP_LARGE_DEVICE, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
status |= mock_expect (&host.flash_mgr.mock, host.flash_mgr.base.set_flash_for_host_access,
|
||||||
|
&host.flash_mgr, 0, MOCK_ARG (&host.control));
|
||||||
|
|
||||||
|
CuAssertIntEquals (test, 0, status);
|
||||||
|
|
||||||
|
status = host.test.base.power_on_reset (&host.test.base, &host.hash.base, &host.rsa.base);
|
||||||
|
CuAssertIntEquals (test, SPI_FLASH_SFDP_LARGE_DEVICE, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_pfm_dirty (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, true, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_bypass_mode (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
status = host_state_manager_is_flash_supported (&host.host_state);
|
||||||
|
CuAssertIntEquals (test, false, status);
|
||||||
|
|
||||||
|
host_processor_dual_testing_validate_and_release (test, &host);
|
||||||
|
}
|
||||||
|
|
||||||
static void host_processor_dual_test_power_on_reset_flash_type_error (CuTest *test)
|
static void host_processor_dual_test_power_on_reset_flash_type_error (CuTest *test)
|
||||||
{
|
{
|
||||||
struct host_processor_dual_testing host;
|
struct host_processor_dual_testing host;
|
||||||
|
@ -11049,6 +11275,18 @@ CuSuite* get_host_processor_dual_power_on_reset_suite ()
|
||||||
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_unsupported_flash);
|
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_unsupported_flash);
|
||||||
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_null);
|
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_null);
|
||||||
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_rot_access_error);
|
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_rot_access_error);
|
||||||
|
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_rot_access_unsupported_device);
|
||||||
|
SUITE_ADD_TEST (suite,
|
||||||
|
host_processor_dual_test_power_on_reset_rot_access_incompatible_spi_master);
|
||||||
|
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_rot_access_no_device);
|
||||||
|
SUITE_ADD_TEST (suite,
|
||||||
|
host_processor_dual_test_power_on_reset_rot_access_no_4byte_addr_commands);
|
||||||
|
SUITE_ADD_TEST (suite,
|
||||||
|
host_processor_dual_test_power_on_reset_rot_access_4byte_addr_incompatible);
|
||||||
|
SUITE_ADD_TEST (suite,
|
||||||
|
host_processor_dual_test_power_on_reset_rot_access_unknown_quad_enable);
|
||||||
|
SUITE_ADD_TEST (suite,
|
||||||
|
host_processor_dual_test_power_on_reset_rot_access_large_device);
|
||||||
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_flash_type_error);
|
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_flash_type_error);
|
||||||
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_flash_type_unsupported_vendor);
|
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_flash_type_unsupported_vendor);
|
||||||
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_flash_type_unsupported_device);
|
SUITE_ADD_TEST (suite, host_processor_dual_test_power_on_reset_flash_type_unsupported_device);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче