// // 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 #include #include #if CONFIG_TRNG_SUPPORT #include #endif #include "bk_general_dma.h" #include #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 \r\n"); } #endif } #if (CONFIG_MPC) #include #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 ", 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); }