blob: a8edf12adbb97285fe9bc094cb7fb223e8f43181 [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/arch/device.h"
#include "sw/device/lib/base/macros.h"
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/dif/dif_sram_ctrl.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_main.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
// define a number of reads and writes to perform,
// for our purposes a small number will be sufficient.
#define SRAM_CTRL_TEST_DATA_SIZE_WORDS 16
OTTF_DEFINE_TEST_CONFIG();
static const uint32_t kStatusRegMask = kDifSramCtrlStatusBusIntegErr |
kDifSramCtrlStatusInitErr |
kDifSramCtrlStatusEscalated;
static const uint32_t kRandomData[SRAM_CTRL_TEST_DATA_SIZE_WORDS] = {
0x6b4abfae, 0x63bdb6e7, 0x87f99b1a, 0xa214dffe, 0xb12291f9, 0xd0cd1abe,
0x5c95e716, 0xe887aab1, 0x307f6ef9, 0x6f5c0464, 0x5882279d, 0x44c19574,
0x1bd20079, 0xf8250ead, 0x4bf362a4, 0xad41437d};
// Buffer to allow the compiler to allocate a safe area in Main SRAM where
// we can do the write/read test without the risk of clobbering data
// used by the program.
OT_SECTION(".data")
static volatile uint32_t sram_main_buffer[SRAM_CTRL_TEST_DATA_SIZE_WORDS];
// Write / Read small chunks of data to SRAM to test
// basic functionality of sram_ctrl
static void write_read_check(mmio_region_t base_addr_region,
const char *sram_name) {
uint32_t rw_data_32;
for (int i = 0; i < SRAM_CTRL_TEST_DATA_SIZE_WORDS; ++i) {
mmio_region_write32(base_addr_region, i * sizeof(uint32_t), kRandomData[i]);
rw_data_32 = mmio_region_read32(base_addr_region, i * sizeof(uint32_t));
CHECK(rw_data_32 == kRandomData[i],
"Memory Write/Read Mismatch for %s, index %d, data read = %08x "
"data_expected = %08x.",
sram_name, i, rw_data_32, kRandomData[i]);
}
}
bool test_main(void) {
// Initialize SRAM_CTRL hardware.
dif_sram_ctrl_t sram_ctrl_main;
dif_sram_ctrl_t sram_ctrl_ret;
CHECK_DIF_OK(dif_sram_ctrl_init(
mmio_region_from_addr(TOP_EARLGREY_SRAM_CTRL_MAIN_REGS_BASE_ADDR),
&sram_ctrl_main));
CHECK_DIF_OK(dif_sram_ctrl_init(
mmio_region_from_addr(TOP_EARLGREY_SRAM_CTRL_RET_AON_REGS_BASE_ADDR),
&sram_ctrl_ret));
dif_sram_ctrl_status_bitfield_t status_main;
dif_sram_ctrl_status_bitfield_t status_ret;
// Check Status registers
CHECK_DIF_OK(dif_sram_ctrl_get_status(&sram_ctrl_ret, &status_ret));
CHECK_DIF_OK(dif_sram_ctrl_get_status(&sram_ctrl_main, &status_main));
CHECK((status_main & kStatusRegMask) == 0x0,
"SRAM main status error bits set, status = %08x.", status_main);
CHECK((status_ret & kStatusRegMask) == 0x0,
"SRAM ret status error bits set, status = %08x.", status_ret);
// Read and Write to/from SRAMs. Main SRAM will use the address of the
// buffer that has been allocated. Ret SRAM can start at the base address.
uintptr_t sram_main_buffer_addr = (uintptr_t)&sram_main_buffer;
mmio_region_t sram_region_main_addr =
mmio_region_from_addr(sram_main_buffer_addr);
mmio_region_t sram_region_ret_base_addr =
mmio_region_from_addr(TOP_EARLGREY_SRAM_CTRL_RET_AON_RAM_BASE_ADDR);
// write / read checks
write_read_check(sram_region_ret_base_addr, "SRAM_RET");
write_read_check(sram_region_main_addr, "SRAM_MAIN");
return true;
}