| // 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; |
| } |