blob: c98370df583369cea1fac6e5a22abb94aa38de32 [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 "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/check.h"
#include "sw/device/lib/testing/sram_ctrl_testutils.h"
#include "sw/device/lib/testing/test_framework/test_main.h"
#include "sw/device/lib/testing/test_framework/test_status.h"
const test_config_t kTestConfig;
static const sram_ctrl_data_t kRamTestPattern1 = {
.words =
{
0xA5A5A5A5,
0xA5A5A5A5,
0xA5A5A5A5,
0xA5A5A5A5,
},
};
static const sram_ctrl_data_t kRamTestPattern2 = {
.words =
{
0x5A5A5A5A,
0x5A5A5A5A,
0x5A5A5A5A,
0x5A5A5A5A,
},
};
/**
* Tests that the written data to RAM can be read.
*
* This is a pre-requisite test to check that RAM can be written and read
* successfully. The test write-read check one pattern, and then the second,
* which prevents a false-negative in case of the value of the memory address
* under test is already initialised to one of the patterns.
*/
static void test_ram_write_read_pattern(const sram_ctrl_t *sram) {
// Write first pattern to the start and the end of RAM.
sram_ctrl_write_to_ram(sram, &kRamTestPattern1);
CHECK(sram_ctrl_read_from_ram_eq(sram, &kRamTestPattern1),
"Read-Write first pattern failed");
// Write second pattern to the start and the end of RAM.
sram_ctrl_write_to_ram(sram, &kRamTestPattern2);
CHECK(sram_ctrl_read_from_ram_eq(sram, &kRamTestPattern2),
"Read-Write second pattern failed");
}
/**
* Tests RAM Scrambling.
*
* This test first writes a pattern to the start and the end of RAM. It then
* requests a new scrambling key via dif_sram_ctrl (which scrambles RAM
* addresses as well as the data). Finally, it reads back the RAM addresses
* and checks them against the original pattern. The test is successful if
* these patterns don't match.
*/
bool test_ram_scrambling(const sram_ctrl_t *sram) {
// Write the pattern at the beginning and the end of RAM.
sram_ctrl_write_to_ram(sram, &kRamTestPattern1);
sram_ctrl_scramble(sram);
// Read the first pattern at the beginning and the end of RAM.
// It should not match the originally written pattern.
return sram_ctrl_read_from_ram_neq(sram, &kRamTestPattern1);
}
bool test_main(void) {
sram_ctrl_t sram = sram_ctrl_ret_init();
test_ram_write_read_pattern(&sram);
// There is a non-zero chance that the value at the tested address by pure
// chance will be the same. So just to be prudent, in case of the failure,
// scrambling is tested again.
if (!test_ram_scrambling(&sram)) {
LOG_WARNING("Initial retention RAM scramble test(s) failed, running again");
CHECK(test_ram_scrambling(&sram),
"Retention RAM Scrambling test has failed (double-checked)");
}
return true;
}