1157 lines
27 KiB
C
Executable File
1157 lines
27 KiB
C
Executable File
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "cli.h"
|
|
|
|
#include <os/os.h>
|
|
#include <driver/psram.h>
|
|
#include <driver/aon_rtc.h>
|
|
#if CONFIG_TRNG_SUPPORT
|
|
#include <driver/trng.h>
|
|
#endif
|
|
#include "bk_general_dma.h"
|
|
#include <driver/dma.h>
|
|
#include "soc/mapping.h"
|
|
#if (CONFIG_CACHE_ENABLE)
|
|
#include "cache.h"
|
|
#endif
|
|
#include "temp_detect_pub.h"
|
|
|
|
#if (CONFIG_PSRAM_AUTO_DETECT)
|
|
#include "bk_ef.h"
|
|
#endif
|
|
|
|
#define TEST_PSRAM_ACCURACY 1
|
|
|
|
#define write_data(addr,val) *((volatile uint32_t *)(addr)) = val
|
|
#define read_data(addr,val) val = *((volatile uint32_t *)(addr))
|
|
#define get_addr_data(addr) *((volatile uint32_t *)(addr))
|
|
|
|
#if (CONFIG_ARCH_RISCV)
|
|
extern u64 riscv_get_mtimer(void);
|
|
#endif
|
|
|
|
static void cli_psram_help(void)
|
|
{
|
|
CLI_LOGI("psram_test {start|stop}\n");
|
|
}
|
|
|
|
#define PSRAM_TEST_LEN (1024 * 4)
|
|
beken_thread_t psram_thread_hdl = NULL;
|
|
|
|
typedef struct {
|
|
uint8_t test_running;
|
|
uint8_t test_mode;
|
|
uint8_t cacheable;
|
|
uint8_t dma_channel;
|
|
uint32_t length;
|
|
uint32_t *data;
|
|
uint32_t delay_time;
|
|
} psram_debug_t;
|
|
|
|
psram_debug_t * psram_debug = NULL;
|
|
|
|
static uint64_t bk_get_current_timer(void)
|
|
{
|
|
uint64_t timer = 0;
|
|
|
|
#ifdef CONFIG_ARCH_RISCV
|
|
timer = riscv_get_mtimer();// tick
|
|
#else // CONFIG_ARCH_RISCV
|
|
|
|
#ifdef CONFIG_AON_RTC
|
|
timer = bk_aon_rtc_get_us();
|
|
#endif
|
|
|
|
#endif // CONFIG_ARCH_RISCV
|
|
|
|
return timer;
|
|
}
|
|
|
|
static uint64_t bk_get_spend_time_us(uint64_t before, uint64_t after)
|
|
{
|
|
uint64_t spend_time = 0;
|
|
|
|
if (after == 0 || before >= after)
|
|
{
|
|
spend_time = 0;
|
|
return spend_time;
|
|
}
|
|
|
|
#ifdef CONFIG_ARCH_RISCV
|
|
spend_time = (after - before) / 26;
|
|
#else // CONFIG_ARCH_RISCV
|
|
|
|
#ifdef CONFIG_AON_RTC
|
|
spend_time = after - before;
|
|
#endif
|
|
|
|
#endif // CONFIG_ARCH_RISCV
|
|
|
|
return spend_time;
|
|
}
|
|
|
|
static void psram_cpu_write_test(void)
|
|
{
|
|
uint32_t i = 0;
|
|
#if TEST_PSRAM_ACCURACY
|
|
uint32_t j = 0;
|
|
uint32_t error_num = 0;
|
|
#endif
|
|
|
|
uint64_t rate = 0;
|
|
uint64_t timer0, timer1;
|
|
uint64_t total_time = 0;
|
|
uint32_t value = 0;
|
|
uint32_t base_addr = 0x60000000;
|
|
|
|
if (psram_debug->cacheable)
|
|
{
|
|
#if !CONFIG_SOC_BK7236XX
|
|
base_addr = 0x64000000;
|
|
#endif
|
|
}
|
|
|
|
#if (CONFIG_PSRAM_APS6408L_O)
|
|
uint32_t test_len = 1024 * 1024 * 8;
|
|
#elif (CONFIG_PSRAM_W955D8MKY_5J)
|
|
uint32_t test_len = 1024 * 1024 * 4;
|
|
#else //CONFIG_PSRAM_APS128XXO_OB9
|
|
uint32_t test_len = 1024 * 1024 * 16;
|
|
#endif
|
|
|
|
CLI_LOGI("begin write %08x-%08x test\r\n", base_addr, base_addr + test_len);
|
|
|
|
timer0 = bk_get_current_timer();
|
|
|
|
#if TEST_PSRAM_ACCURACY
|
|
for (j = 0; j < test_len / psram_debug->length; j ++)
|
|
{
|
|
for (i = 0; i < psram_debug->length; i += 4)
|
|
write_data((base_addr + i + (j << 15)), psram_debug->data[(i >> 2) & 0x1FFF]);
|
|
}
|
|
#else
|
|
for (i = 0; i < test_len; i +=4)
|
|
{
|
|
write_data(base_addr + i, 0x11223344);
|
|
}
|
|
#endif
|
|
|
|
timer1 = bk_get_current_timer();
|
|
|
|
if (timer1 > timer0)
|
|
{
|
|
total_time = bk_get_spend_time_us(timer0, timer1);
|
|
rate = ((uint64_t)test_len) * 1000000 / total_time;
|
|
CLI_LOGI("finish write, use time: %ld ms, write_rate:%ld%ld byte/s\r\n", (uint32_t)(total_time / 1000),
|
|
(uint32_t)(rate >> 32), (uint32_t)(rate & 0xFFFFFFFF));
|
|
}
|
|
|
|
CLI_LOGI("begin read %08x-%08x test\r\n", base_addr, base_addr + test_len);
|
|
|
|
timer0 = bk_get_current_timer();
|
|
|
|
for (i = 0; i < test_len / 4; i++)
|
|
read_data((base_addr + i * 0x4), value);
|
|
|
|
timer1 = bk_get_current_timer();
|
|
if (timer1 > timer0)
|
|
{
|
|
total_time = bk_get_spend_time_us(timer0, timer1);
|
|
rate = ((uint64_t)test_len) * 1000000 / total_time;
|
|
CLI_LOGI("finish read, use time: %ld ms, read_rate:%d%ld byte/s\r\n", (uint32_t)(total_time / 1000),
|
|
(uint32_t)(rate >> 32), (uint32_t)(rate & 0xFFFFFFFF));
|
|
}
|
|
|
|
CLI_LOGI("%s, %d\r\n", __func__, value);
|
|
|
|
#if TEST_PSRAM_ACCURACY
|
|
for (i = 0; i < test_len / 4; i++)
|
|
{
|
|
value = get_addr_data(base_addr + i * 0x4);
|
|
if (value != (psram_debug->data[i & 0x1FFF]))
|
|
{
|
|
CLI_LOGI("==========%08x %08x %08x=======\n", value, psram_debug->data[i & 0x1FFF], value^psram_debug->data[i & 0x1FFF]);
|
|
error_num++;
|
|
}
|
|
}
|
|
|
|
CLI_LOGI("finish compare, error_num: %ld, corr_rate: %ld.\r\n", error_num, ((test_len / 4 - error_num) * 100 / (test_len / 4)));
|
|
#endif
|
|
|
|
rtos_delay_milliseconds(psram_debug->delay_time);
|
|
|
|
}
|
|
|
|
static bk_err_t psram_dma_memcpy_by_chnl(void *out, const void *in, uint32_t len, dma_id_t cpy_chnl)
|
|
{
|
|
dma_config_t dma_config = {0};
|
|
|
|
dma_config.mode = DMA_WORK_MODE_SINGLE;
|
|
dma_config.chan_prio = 0;
|
|
|
|
dma_config.src.dev = DMA_DEV_DTCM;
|
|
dma_config.src.width = DMA_DATA_WIDTH_32BITS;
|
|
dma_config.src.addr_inc_en = DMA_ADDR_INC_ENABLE;
|
|
dma_config.src.start_addr = (uint32_t)in;
|
|
dma_config.src.end_addr = (uint32_t)(in + len);
|
|
|
|
dma_config.dst.dev = DMA_DEV_DTCM;
|
|
dma_config.dst.width = DMA_DATA_WIDTH_32BITS;
|
|
dma_config.dst.addr_inc_en = DMA_ADDR_INC_ENABLE;
|
|
dma_config.dst.start_addr = (uint32_t)out;
|
|
dma_config.dst.end_addr = (uint32_t)(out + len);
|
|
|
|
|
|
bk_dma_init(cpy_chnl, &dma_config);
|
|
bk_dma_set_transfer_len(cpy_chnl, len);
|
|
#if (CONFIG_SPE)
|
|
|
|
if (psram_debug->cacheable)
|
|
{
|
|
bk_dma_set_src_burst_len(cpy_chnl, BURST_LEN_INC8);
|
|
bk_dma_set_dest_burst_len(cpy_chnl, BURST_LEN_INC8);
|
|
}
|
|
|
|
bk_dma_set_src_sec_attr(cpy_chnl, DMA_ATTR_SEC);
|
|
bk_dma_set_dest_sec_attr(cpy_chnl, DMA_ATTR_SEC);
|
|
#endif
|
|
bk_dma_start(cpy_chnl);
|
|
|
|
BK_WHILE(bk_dma_get_enable_status(cpy_chnl));
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
static void psram_dma_write_test(void)
|
|
{
|
|
uint32_t i = 0;
|
|
uint32_t error_num = 0;
|
|
uint64_t rate = 0;
|
|
uint64_t timer0, timer1;
|
|
uint32_t total_time = 0;
|
|
|
|
uint32_t value = 0;
|
|
uint32_t base_addr = 0x60000000;
|
|
|
|
if (psram_debug->cacheable)
|
|
{
|
|
#if !CONFIG_SOC_BK7236XX
|
|
base_addr = 0x64000000;
|
|
#endif
|
|
}
|
|
|
|
#if (CONFIG_PSRAM_APS6408L_O)
|
|
uint32_t test_len = 1024 * 1024 * 8;
|
|
#elif (CONFIG_PSRAM_W955D8MKY_5J)
|
|
uint32_t test_len = 1024 * 1024 * 4;
|
|
#else //CONFIG_PSRAM_APS128XXO_OB9
|
|
uint32_t test_len = 1024 * 1024 * 16;
|
|
#endif
|
|
|
|
CLI_LOGI("begin write %08x-%08x test\r\n", base_addr, base_addr + test_len);
|
|
|
|
timer0 = bk_get_current_timer();
|
|
|
|
for (i = 0; i < test_len / psram_debug->length; i++)
|
|
{
|
|
psram_dma_memcpy_by_chnl((void *)(base_addr + i * psram_debug->length), psram_debug->data, psram_debug->length, psram_debug->dma_channel);
|
|
}
|
|
|
|
timer1 = bk_get_current_timer();
|
|
if (timer1 > timer0)
|
|
{
|
|
total_time = bk_get_spend_time_us(timer0, timer1);
|
|
rate = (test_len) * 8 / total_time;
|
|
CLI_LOGI("finish write, use time: %ld ms, write_rate:%d Mbps\r\n", (uint32_t)(total_time / 1000), rate);
|
|
}
|
|
|
|
CLI_LOGI("begin read %08x-%08x test\r\n", base_addr, base_addr + test_len);
|
|
|
|
timer0 = bk_get_current_timer();
|
|
|
|
for (i = 0; i < test_len / 4; i++)
|
|
read_data((base_addr + i * 0x4), value);
|
|
|
|
timer1 = bk_get_current_timer();
|
|
if (timer1 > timer0)
|
|
{
|
|
total_time = bk_get_spend_time_us(timer0, timer1);
|
|
rate = ((uint64_t)test_len) * 8/ total_time;
|
|
CLI_LOGI("finish read, use time: %ld ms, read_rate:%d Mbps\r\n", (uint32_t)(total_time / 1000), rate);
|
|
}
|
|
|
|
for (i = 0; i < test_len / psram_debug->length; i++)
|
|
{
|
|
for (uint32_t k = 0; k < psram_debug->length / 4; k++)
|
|
{
|
|
value = get_addr_data(base_addr + i * psram_debug->length + k * 0x4);
|
|
|
|
if (value != psram_debug->data[k])
|
|
{
|
|
CLI_LOGI("==========%08x %08x %08x=======\n", value, psram_debug->data[k], value^psram_debug->data[k]);
|
|
error_num++;
|
|
}
|
|
}
|
|
}
|
|
|
|
CLI_LOGI("finish compare, error_num: %ld, corr_rate: %ld.\r\n", error_num, ((test_len / 4 - error_num) * 100 / (test_len / 4)));
|
|
|
|
rtos_delay_milliseconds(psram_debug->delay_time);
|
|
|
|
}
|
|
|
|
static void psram_write_continue_test(void)
|
|
{
|
|
uint32_t i = 0;
|
|
uint32_t error_num = 0;
|
|
uint64_t rate = 0;
|
|
uint64_t timer0, timer1;
|
|
uint32_t total_time = 0;
|
|
|
|
uint32_t value = 0;
|
|
uint32_t base_addr = 0x60000000;
|
|
|
|
if (psram_debug->cacheable)
|
|
{
|
|
#if !CONFIG_SOC_BK7236XX
|
|
base_addr = 0x64000000;
|
|
#endif
|
|
}
|
|
|
|
#if (CONFIG_PSRAM_APS6408L_O)
|
|
uint32_t test_len = 1024 * 1024 * 8;
|
|
#elif (CONFIG_PSRAM_W955D8MKY_5J)
|
|
uint32_t test_len = 1024 * 1024 * 4;
|
|
#else //CONFIG_PSRAM_APS128XXO_OB9
|
|
uint32_t test_len = 1024 * 1024 * 16;
|
|
#endif
|
|
|
|
|
|
CLI_LOGI("begin write %08x-%08x test\r\n", base_addr, base_addr + test_len);
|
|
timer0 = bk_get_current_timer();
|
|
for (i = 0; i < test_len; i += psram_debug->length)
|
|
{
|
|
bk_psram_memcpy((uint8_t *)(base_addr + i), (uint8_t *)&psram_debug->data[0], psram_debug->length);
|
|
}
|
|
|
|
timer1 = bk_get_current_timer();
|
|
if (timer1 > timer0)
|
|
{
|
|
total_time = bk_get_spend_time_us(timer0, timer1);
|
|
rate = ((uint64_t)test_len) * 1000000 / total_time;
|
|
CLI_LOGI("finish write, use time: %ld ms, write_rate:%d%ld byte/s\r\n", (uint32_t)(total_time / 1000),
|
|
(uint32_t)(rate >> 32), (uint32_t)(rate & 0xFFFFFFFF));
|
|
}
|
|
|
|
|
|
CLI_LOGI("begin read %08x-%08x test\r\n", base_addr, base_addr + test_len);
|
|
timer0 = bk_get_current_timer();
|
|
for (i = 0; i < test_len / 4; i++)
|
|
read_data((base_addr + i * 0x4), value);
|
|
|
|
timer1 = bk_get_current_timer();
|
|
if (timer1 > timer0)
|
|
{
|
|
total_time = bk_get_spend_time_us(timer0, timer1);
|
|
rate = ((uint64_t)test_len) * 1000000 / total_time;
|
|
CLI_LOGI("finish read, use time: %ld ms, read_rate:%d%ld byte/s\r\n", (uint32_t)(total_time / 1000),
|
|
(uint32_t)(rate >> 32), (uint32_t)(rate & 0xFFFFFFFF));
|
|
}
|
|
|
|
for (i = 0; i < test_len / psram_debug->length; i++)
|
|
{
|
|
for (uint32_t k = 0; k < psram_debug->length / 4; k++)
|
|
{
|
|
value = get_addr_data(base_addr + i * psram_debug->length + k * 0x4);
|
|
|
|
if (value != psram_debug->data[k])
|
|
{
|
|
error_num++;
|
|
}
|
|
}
|
|
}
|
|
|
|
CLI_LOGI("finish compare, error_num: %ld, corr_rate: %ld.\r\n", error_num, (test_len / 4 - error_num) * 100 / (test_len / 4));
|
|
|
|
rtos_delay_milliseconds(psram_debug->delay_time);
|
|
|
|
}
|
|
|
|
static void psram_test_unit(void)
|
|
{
|
|
#if (CONFIG_BK7256_SOC)
|
|
|
|
uint32_t i = 0;
|
|
uint32_t error_num = 0;
|
|
uint64_t rate = 0;
|
|
uint64_t timer0, timer1;
|
|
uint32_t total_time = 0;
|
|
|
|
uint32_t start_address = (uint32_t)&psram_map->reserved;
|
|
uint32_t end_address = (8 * 1024 * 1024 + 0x60000000);
|
|
uint32_t test_len = end_address - start_address;
|
|
|
|
uint32_t value = 0;
|
|
CLI_LOGI("begin write %08X-%08X, count: %d\n", start_address, end_address, test_len / 4);
|
|
|
|
timer0 = bk_get_current_timer();
|
|
|
|
for (i = 0; i < test_len / 4; i++)
|
|
write_data((start_address + i * 0x4), 0x11111111 + i);
|
|
|
|
timer1 = bk_get_current_timer();
|
|
if (timer1 > timer0)
|
|
{
|
|
total_time = bk_get_spend_time_us(timer0, timer1);
|
|
rate = ((uint64_t)test_len) * 1000000 / total_time;
|
|
CLI_LOGI("finish write, use time: %ld ms, write_rate:%d%ld byte/s\r\n", (uint32_t)(total_time / 1000),
|
|
(uint32_t)(rate >> 32), (uint32_t)(rate & 0xFFFFFFFF));
|
|
}
|
|
|
|
|
|
|
|
CLI_LOGI("begin write %08X-%08X, count: %d\n", start_address, end_address, test_len);
|
|
timer0 = bk_get_current_timer();
|
|
for (i = 0; i < test_len / 4; i++)
|
|
read_data((start_address + i * 0x4), value);
|
|
|
|
timer1 = bk_get_current_timer();
|
|
if (timer1 > timer0)
|
|
{
|
|
total_time = bk_get_spend_time_us(timer0, timer1);
|
|
rate = ((uint64_t)test_len) * 1000000 / total_time;
|
|
CLI_LOGI("finish read, use time: %ld ms, read_rate:%d%ld byte/s\r\n", (uint32_t)(total_time / 1000),
|
|
(uint32_t)(rate >> 32), (uint32_t)(rate & 0xFFFFFFFF));
|
|
}
|
|
|
|
|
|
|
|
CLI_LOGI("begin write %08X-%08X, count: %d\n", start_address, end_address, test_len);
|
|
|
|
for (i = 0; i < test_len / 4; i++)
|
|
{
|
|
value = get_addr_data(start_address + i * 0x4);
|
|
if (value != (0x11111111 + i))
|
|
error_num++;
|
|
}
|
|
|
|
CLI_LOGI("finish compare, error_num: %ld, corr_rate: %ld\n", error_num, ((test_len / 4 - error_num) * 100 / (test_len / 4 ));
|
|
|
|
rtos_delay_milliseconds(psram_debug->delay_time);
|
|
#endif
|
|
}
|
|
|
|
//TODO fix/refactoring it during v5 verification
|
|
static uint32_t psram_calibrate_read_write_test(uint32_t start_address, uint32_t test_len)
|
|
{
|
|
uint32_t error_num = 0;
|
|
uint32_t value = 0;
|
|
uint32_t i = 0;
|
|
|
|
for (i = 0; i < test_len / 4; i++)
|
|
write_data((start_address + i * 0x4), 0x11111111 + i);
|
|
|
|
for (i = 0; i < test_len / 4; i++)
|
|
{
|
|
value = get_addr_data(start_address + i * 0x4);
|
|
if (value != (0x11111111 + i))
|
|
error_num++;
|
|
}
|
|
|
|
return error_num;
|
|
}
|
|
|
|
static void psram_calibrate_test(void)
|
|
{
|
|
#if CNOFIG_PSRAM_CALIBRATE
|
|
static uint32_t s_temperature = 0;
|
|
uint32_t cur_temperature = -1;
|
|
uint32_t err_cnt = 0;
|
|
uint32_t v = 0;
|
|
|
|
if (BK_OK != temp_detect_get_temperature(&cur_temperature)) {
|
|
CLI_LOGE("failed to get temperature\r\n");
|
|
return;
|
|
}
|
|
|
|
uint32_t diff = (cur_temperature > s_temperature) ? (cur_temperature - s_temperature) : (s_temperature - cur_temperature);
|
|
if (diff > 100 ) { //TODO give a reasonable value
|
|
for (int i = 0; i < 63; i++) {
|
|
uint32_t v = (i & 7) | ((i & ~7) << 3);
|
|
REG_WRITE(0x46080000 + (5 << 2), v);
|
|
err_cnt = psram_calibrate_read_write_test(0x60000000, 10240);
|
|
if (err_cnt) {
|
|
os_printf("%d %d %d %d %d\r\n", cur_temperature, (i & 7), (i >> 6) & 3, (i >> 8) & 3, err_cnt);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static void psram_test_main(void)
|
|
{
|
|
while (psram_debug->test_running)
|
|
{
|
|
if (psram_debug->test_mode == 0)
|
|
{
|
|
psram_cpu_write_test();
|
|
} else if (psram_debug->test_mode == 1) {
|
|
psram_test_unit();
|
|
} else if (psram_debug->test_mode == 2) {
|
|
psram_write_continue_test();
|
|
} else if (psram_debug->test_mode == 3) {
|
|
psram_dma_write_test();
|
|
} else {
|
|
psram_calibrate_test();
|
|
}
|
|
}
|
|
|
|
CLI_LOGI("psram_test task exit\n");
|
|
|
|
if (psram_debug)
|
|
{
|
|
if (psram_debug->data)
|
|
{
|
|
os_free(psram_debug->data);
|
|
psram_debug->data = NULL;
|
|
}
|
|
|
|
bk_dma_free(DMA_DEV_DTCM, psram_debug->dma_channel);
|
|
|
|
os_free(psram_debug);
|
|
psram_debug = NULL;
|
|
}
|
|
|
|
psram_thread_hdl = NULL;
|
|
rtos_delete_thread(NULL);
|
|
}
|
|
|
|
static bk_err_t psram_task_init(void)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
if (!psram_thread_hdl)
|
|
{
|
|
ret = rtos_create_thread(&psram_thread_hdl,
|
|
4,
|
|
"psram_debug",
|
|
(beken_thread_function_t)psram_test_main,
|
|
4 * 1024,
|
|
(beken_thread_arg_t)NULL);
|
|
if (ret != BK_OK)
|
|
{
|
|
psram_thread_hdl = NULL;
|
|
CLI_LOGE("Error: Failed to create psram test task: %d\r\n", ret);
|
|
return BK_ERR_NOT_INIT;
|
|
}
|
|
|
|
return BK_OK;
|
|
}
|
|
else
|
|
return BK_OK;
|
|
}
|
|
|
|
static void cli_psram_cmd_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
|
{
|
|
char *msg = NULL;
|
|
|
|
if (os_strcmp(argv[1], "start") == 0)
|
|
{
|
|
bk_psram_init();
|
|
|
|
psram_debug = (psram_debug_t *)os_malloc(sizeof(psram_debug_t));
|
|
|
|
if (psram_debug == NULL)
|
|
{
|
|
CLI_LOGE("psram test malloc failed!\r\n");
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
|
|
return;
|
|
}
|
|
|
|
os_memset(psram_debug, 0, sizeof(psram_debug_t));
|
|
|
|
if (psram_debug->data == NULL)
|
|
{
|
|
psram_debug->length = 1024 * 32;
|
|
psram_debug->data = (uint32_t *)os_malloc(psram_debug->length);
|
|
if (psram_debug->data == NULL)
|
|
{
|
|
CLI_LOGE("malloc error!\r\n");
|
|
os_free(psram_debug);
|
|
psram_debug = NULL;
|
|
return;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < psram_debug->length / 4; i++)
|
|
{
|
|
#if CONFIG_TRNG_SUPPORT
|
|
psram_debug->data[i] = bk_rand() + i;
|
|
#else
|
|
psram_debug->data[i] = 0xA55AA55A + i + (i << 8) + (i << 16) + (i << 24);
|
|
#endif
|
|
}
|
|
|
|
psram_debug->test_running = 1;
|
|
|
|
if (os_strcmp(argv[2], "cpu") == 0)
|
|
{
|
|
psram_debug->test_mode = 0;
|
|
}
|
|
else if (os_strcmp(argv[2], "conexist") == 0)
|
|
{
|
|
psram_debug->test_mode = 1;
|
|
}
|
|
else if (os_strcmp(argv[2], "continue_write") == 0)
|
|
{
|
|
psram_debug->test_mode = 2;
|
|
} else if (os_strcmp(argv[2], "dma") == 0) {
|
|
psram_debug->test_mode = 3;
|
|
psram_debug->dma_channel = bk_dma_alloc(DMA_DEV_DTCM);
|
|
} else if (os_strcmp(argv[2], "calibrate") == 0) {
|
|
psram_debug->test_mode = 4;
|
|
}
|
|
|
|
if (os_strcmp(argv[3], "1") == 0)
|
|
{
|
|
psram_debug->cacheable = 1;
|
|
}
|
|
else
|
|
{
|
|
psram_debug->cacheable = 0;
|
|
}
|
|
|
|
psram_debug->delay_time = 500;
|
|
|
|
if (argc >= 5)
|
|
{
|
|
psram_debug->delay_time = os_strtoul(argv[4], NULL, 10);
|
|
|
|
if (psram_debug->delay_time == 0)
|
|
psram_debug->delay_time = 500;
|
|
}
|
|
|
|
if (psram_task_init() != kNoErr)
|
|
{
|
|
CLI_LOGE("psram test failed!\r\n");
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
|
|
return;
|
|
}
|
|
|
|
CLI_LOGI("psram test start success!\r\n");
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
}
|
|
else if (os_strcmp(argv[1], "stop") == 0)
|
|
{
|
|
if (psram_thread_hdl)
|
|
{
|
|
psram_debug->test_running = 0;
|
|
}
|
|
|
|
while (psram_thread_hdl)
|
|
{
|
|
rtos_delay_milliseconds(10);
|
|
}
|
|
|
|
bk_psram_deinit();
|
|
CLI_LOGI("psram test stop success!\r\n");
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
}
|
|
else if (os_strcmp(argv[1], "strcat") == 0)
|
|
{
|
|
uint8_t *data = psram_malloc(20);
|
|
if (data == NULL)
|
|
{
|
|
CLI_LOGI("psram malloc error!\r\n");
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
|
|
return;
|
|
}
|
|
os_memset(data, 0, 20);
|
|
bk_psram_strcat((char *)data, (char *)argv[2]);
|
|
bk_psram_strcat((char *)data, (char *)argv[2]);
|
|
bk_psram_strcat((char *)data, (char *)argv[2]);
|
|
psram_free(data);
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
}
|
|
else
|
|
{
|
|
cli_psram_help();
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
}
|
|
|
|
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
|
|
}
|
|
|
|
static uint32_t test_frame_strip(uint8_t *src, uint32_t size)
|
|
{
|
|
uint8_t sram_tmp[16] = {0x71, 0xfb, 0x84, 0x1f, 0x53, 0x5a, 0xd9, 0xd9, 0x8e, 0xd2, 0x76, 0x3f, 0xff, 0xff, 0xff, 0xd9};
|
|
|
|
static uint8_t flag = 0;
|
|
flag ++;
|
|
sram_tmp[0] += flag;
|
|
|
|
{
|
|
os_printf("1====>>>> %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %p %d\n",
|
|
src[size - 16], src[size - 15], src[size - 14], src[size - 13],
|
|
src[size - 12], src[size - 11], src[size - 10], src[size - 9],
|
|
src[size - 8], src[size - 7], src[size - 6], src[size - 5],
|
|
src[size - 4], src[size - 3], src[size - 2], src[size - 1], src, size);
|
|
// for (uint8_t i = 0; i < 16; i++)
|
|
// {
|
|
// src[i] = sram_tmp[i];
|
|
// }
|
|
bk_psram_word_memcpy(src, sram_tmp, 16);
|
|
|
|
os_printf("2===>>> %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %p %d\n",
|
|
src[size - 16], src[size - 15], src[size - 14], src[size - 13],
|
|
src[size - 12], src[size - 11], src[size - 10], src[size - 9],
|
|
src[size - 8], src[size - 7], src[size - 6], src[size - 5],
|
|
src[size - 4], src[size - 3], src[size - 2], src[size - 1], src, size);
|
|
|
|
#if (CONFIG_CACHE_ENABLE)
|
|
flush_dcache(src, 16);
|
|
#endif
|
|
|
|
os_printf("3==>> %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %p %d\n",
|
|
src[size - 16], src[size - 15], src[size - 14], src[size - 13],
|
|
src[size - 12], src[size - 11], src[size - 10], src[size - 9],
|
|
src[size - 8], src[size - 7], src[size - 6], src[size - 5],
|
|
src[size - 4], src[size - 3], src[size - 2], src[size - 1], src, size);
|
|
|
|
bk_psram_word_memcpy(src, sram_tmp, 16);
|
|
|
|
os_printf("4=> %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %p %d\n",
|
|
src[size - 16], src[size - 15], src[size - 14], src[size - 13],
|
|
src[size - 12], src[size - 11], src[size - 10], src[size - 9],
|
|
src[size - 8], src[size - 7], src[size - 6], src[size - 5],
|
|
src[size - 4], src[size - 3], src[size - 2], src[size - 1], src, size);
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
|
|
void cli_test_psram_cache_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
|
{
|
|
#if CONFIG_DEBUG_FIRMWARE
|
|
uint32_t address, size;
|
|
os_printf("cli_test_psram_cache_cmd\r\n");
|
|
if (argc >= 3)
|
|
{
|
|
address = strtoll(argv[1], NULL, 16);
|
|
size = strtoll(argv[2], NULL, 16);
|
|
os_printf("test psram cache, address: 0x%08X size: 0x%08X\r\n", address, 16);
|
|
|
|
test_frame_strip((uint8_t *)address, size);
|
|
} else {
|
|
os_printf("psram_cache <addr> <size>\r\n");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#if (CONFIG_MPC)
|
|
#include <driver/mpc.h>
|
|
|
|
#define BUFFER_SIZE (34)
|
|
#define TEST_VALUE_START 0x41
|
|
|
|
static void fill_buffer(uint8_t *pBuffer, uint32_t uwBufferLenght, uint32_t uwOffset)
|
|
{
|
|
uint32_t tmpIndex = 0;
|
|
|
|
/* Put in global buffer different values */
|
|
for (tmpIndex = 0; tmpIndex < uwBufferLenght; tmpIndex++ ) {
|
|
pBuffer[tmpIndex] = tmpIndex + uwOffset;
|
|
}
|
|
}
|
|
|
|
static void cli_psram_test(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
|
{
|
|
int i;
|
|
uint8_t *test_addr_sec = NULL;
|
|
char *msg = NULL;
|
|
uint8_t psram_tx_buffer[BUFFER_SIZE] = {0};
|
|
uint8_t psram_rx_buffer[BUFFER_SIZE] = {0};
|
|
|
|
fill_buffer(psram_tx_buffer, BUFFER_SIZE, TEST_VALUE_START);
|
|
|
|
/*set first block non-sec and second block sec*/
|
|
bk_mpc_driver_init();
|
|
bk_mpc_set_secure_attribute(MPC_DEV_PSRAM, 0, 1, MPC_BLOCK_NON_SECURE);
|
|
bk_mpc_set_secure_attribute(MPC_DEV_PSRAM, bk_mpc_get_block_size(MPC_DEV_PSRAM), 1, MPC_BLOCK_SECURE);
|
|
|
|
test_addr_sec = (uint8_t *)(SOC_PSRAM_DATA_ADDR_SEC + bk_mpc_get_block_size(MPC_DEV_PSRAM));
|
|
bk_psram_memcpy(test_addr_sec, psram_tx_buffer, BUFFER_SIZE);
|
|
bk_psram_memread(test_addr_sec, psram_rx_buffer, BUFFER_SIZE);
|
|
|
|
for (i = 0; i < BUFFER_SIZE; i++) {
|
|
bk_printf("%02x ", psram_rx_buffer[i]);
|
|
}
|
|
bk_printf("\r\n");
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
|
|
}
|
|
#endif
|
|
|
|
|
|
static void cli_psram_cmd_handle_ext(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
|
{
|
|
uint32_t addr = 0x60000000;
|
|
uint32_t i = 0;
|
|
uint32_t length = 512;
|
|
char *msg = NULL;
|
|
|
|
if (argc < 2)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
goto out;
|
|
}
|
|
|
|
if (os_strcmp(argv[1], "init") == 0)
|
|
{
|
|
/*init psram*/
|
|
bk_psram_init();
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
}
|
|
else if (os_strcmp(argv[1], "delete_flash") == 0)
|
|
{
|
|
#if (CONFIG_PSRAM_AUTO_DETECT)
|
|
bk_set_env_enhance(PSRAM_CHIP_ID, NULL, 0);
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
#else
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
#endif
|
|
}
|
|
else if (os_strcmp(argv[1], "clk") == 0)
|
|
{
|
|
uint16_t clk = os_strtoul(argv[2], NULL, 10);
|
|
|
|
switch (clk)
|
|
{
|
|
case 80:
|
|
bk_psram_set_clk(PSRAM_80M);
|
|
break;
|
|
|
|
case 120:
|
|
bk_psram_set_clk(PSRAM_120M);
|
|
break;
|
|
|
|
case 160:
|
|
bk_psram_set_clk(PSRAM_160M);
|
|
break;
|
|
|
|
case 240:
|
|
bk_psram_set_clk(PSRAM_240M);
|
|
break;
|
|
|
|
default:
|
|
CLI_LOGE("can not support this clk!\r\n");
|
|
break;
|
|
}
|
|
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
}
|
|
else if (os_strcmp(argv[1], "byte") == 0)
|
|
{
|
|
uint8_t value = 0;
|
|
if (argc < 4)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
goto out;
|
|
}
|
|
|
|
addr = os_strtoul(argv[2], NULL, 16);
|
|
length = os_strtoul(argv[3], NULL, 10);
|
|
if (length & 0x3)
|
|
{
|
|
length = ((length >> 2) + 1) << 2;
|
|
}
|
|
|
|
if (addr > 0x60800000 || addr < 0x60000000 || length == 0)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < length; i++)
|
|
{
|
|
*((volatile uint8_t *)addr + i) = i;
|
|
}
|
|
|
|
for (i = 0; i < length; i++)
|
|
{
|
|
value = *((volatile uint8_t *)addr + i);
|
|
|
|
if (value != (i % 256))
|
|
{
|
|
CLI_LOGI("index:%d, value:%d\r\n", i, value);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i < length)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
}
|
|
else
|
|
{
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
}
|
|
}
|
|
}
|
|
else if (os_strcmp(argv[1], "word") == 0)
|
|
{
|
|
if (argc < 4)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
goto out;
|
|
}
|
|
|
|
addr = os_strtoul(argv[2], NULL, 16);
|
|
length = os_strtoul(argv[3], NULL, 10);
|
|
if (length & 0x3)
|
|
{
|
|
length = ((length >> 2) + 1) << 2;
|
|
}
|
|
|
|
if (addr > 0x60800000 || addr < 0x60000000 || length == 0)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < length; i += 4)
|
|
{
|
|
*(((volatile uint32_t *)(addr + i))) = (i << 24) + (i << 16) + (i << 8) + i + 0x11223344;
|
|
}
|
|
}
|
|
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
}
|
|
else if (os_strcmp(argv[1], "rewrite") == 0)
|
|
{
|
|
if (argc < 3)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
goto out;
|
|
}
|
|
|
|
addr = os_strtoul(argv[2], NULL, 16);
|
|
length = 20;
|
|
|
|
if (addr > 0x60800000 || addr < 0x60000000 || length == 0)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
goto out;
|
|
}
|
|
|
|
for (i = 0; i < length; i += 4)
|
|
{
|
|
*(((volatile uint32_t *)(addr + i))) = 0x11111111 * i + 0x11223344;
|
|
}
|
|
|
|
for (i = 0; i < length * 100; i++)
|
|
{
|
|
*((volatile uint32_t *)addr) = 0x44332211;
|
|
}
|
|
|
|
for (i = 0; i < length; i ++)
|
|
{
|
|
CLI_LOGI("0x%08x\r\n", *((volatile uint32_t *)(addr + i * 4)));
|
|
}
|
|
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
}
|
|
else if (os_strcmp(argv[1], "read") == 0)
|
|
{
|
|
if (argc < 4)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
goto out;
|
|
}
|
|
|
|
addr = os_strtoul(argv[2], NULL, 16);
|
|
length = os_strtoul(argv[3], NULL, 10);
|
|
if (length & 0x3)
|
|
{
|
|
length = ((length >> 2) + 1) << 2;
|
|
}
|
|
|
|
if (length == 0)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
}
|
|
else
|
|
{
|
|
uint8_t *src = (uint8_t *)addr;
|
|
|
|
for (i = 0; i < length; i++)
|
|
{
|
|
if ((i % 32) == 0)
|
|
{
|
|
CLI_LOGI("\r\n");
|
|
}
|
|
|
|
CLI_LOGI("%02x ", *(src + i));
|
|
}
|
|
CLI_LOGI("\r\n");
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
}
|
|
}
|
|
else if (os_strcmp(argv[1], "cache") == 0)
|
|
{
|
|
if (argc < 4)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
goto out;
|
|
}
|
|
|
|
addr = os_strtoul(argv[2], NULL, 16);
|
|
length = os_strtoul(argv[3], NULL, 10);
|
|
if (length & 0x3)
|
|
{
|
|
length = ((length >> 2) + 1) << 2;
|
|
}
|
|
|
|
if (length == 0)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
}
|
|
else
|
|
{
|
|
#if (CONFIG_CACHE_ENABLE)
|
|
flush_dcache((uint8_t *)addr, length);
|
|
#endif
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
}
|
|
}
|
|
else if (os_strcmp(argv[1], "cover_write") == 0)
|
|
{
|
|
int ret = 0;
|
|
uint32_t start = 0, end = 0;
|
|
uint8_t enable = 0;
|
|
uint8_t id = 0;
|
|
|
|
if (argc < 4)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
goto out;
|
|
}
|
|
|
|
id = os_strtoul(argv[2], NULL, 10);
|
|
|
|
if (os_strcmp(argv[3], "1") == 0)
|
|
{
|
|
if (argc < 6)
|
|
{
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
goto out;
|
|
}
|
|
enable = 1;
|
|
start = os_strtoul(argv[4], NULL, 16);
|
|
end = os_strtoul(argv[5], NULL, 16);
|
|
}
|
|
|
|
else
|
|
enable = 0;
|
|
|
|
if (enable)
|
|
ret = bk_psram_enable_write_through(id, start, end);
|
|
else
|
|
ret = bk_psram_disable_write_through(id);
|
|
|
|
if (ret == BK_OK)
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
else
|
|
msg = CLI_CMD_RSP_ERROR;
|
|
}
|
|
else if (os_strcmp(argv[1], "deinit") == 0)
|
|
{
|
|
/*init psram*/
|
|
bk_psram_deinit();
|
|
msg = CLI_CMD_RSP_SUCCEED;
|
|
}
|
|
|
|
out:
|
|
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
|
|
}
|
|
|
|
|
|
beken_thread_t psram_task_hdl = NULL;
|
|
|
|
static void psram_task_main(void)
|
|
{
|
|
while (1) {
|
|
rtos_delay_milliseconds(3000);
|
|
CLI_LOGI("psram_task_main is running.\r\n");
|
|
}
|
|
|
|
psram_task_hdl = NULL;
|
|
rtos_delete_thread(NULL);
|
|
}
|
|
|
|
static void cli_create_psram_task_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
if (!psram_task_hdl)
|
|
{
|
|
ret = rtos_create_psram_thread(&psram_task_hdl,
|
|
4,
|
|
"psram_task",
|
|
(beken_thread_function_t)psram_task_main,
|
|
4 * 1024,
|
|
(beken_thread_arg_t)NULL);
|
|
if (ret != BK_OK)
|
|
{
|
|
psram_task_hdl = NULL;
|
|
CLI_LOGE("Error: Failed to create psram test task: %d\r\n", ret);
|
|
return;
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
static void cli_delete_psram_task_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
|
{
|
|
if(psram_task_hdl) {
|
|
rtos_delete_thread(&psram_task_hdl);
|
|
psram_task_hdl = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
#define PSRAM_CNT (sizeof(s_psram_commands) / sizeof(struct cli_command))
|
|
static const struct cli_command s_psram_commands[] = {
|
|
{"psram_test_ext", "init|byte|word|rewirte|deinit", cli_psram_cmd_handle_ext},
|
|
{"psram_test", "start|stop", cli_psram_cmd_handle},
|
|
{"psram_cache", "psram_cache <addr> <size>", cli_test_psram_cache_cmd},
|
|
#if (CONFIG_MPC)
|
|
{"psram_mpc", "", cli_psram_test},
|
|
#endif
|
|
{"psram_task_create", "create task on psram", cli_create_psram_task_handle},
|
|
{"psram_task_delete", "delete task on psram", cli_delete_psram_task_handle},
|
|
};
|
|
|
|
int cli_psram_init(void)
|
|
{
|
|
return cli_register_commands(s_psram_commands, PSRAM_CNT);
|
|
}
|
|
|
|
|