181 lines
5.1 KiB
C
181 lines
5.1 KiB
C
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
#include "chip_reg_base.h"
|
|
#include "hw_reg_api.h"
|
|
#include "sfc_rf.h"
|
|
#include "apb_cache_reg.h"
|
|
|
|
#include "ahb.h"
|
|
#include "cpu.h"
|
|
#include "gp_timer.h"
|
|
#include "iot_spinlock.h"
|
|
|
|
#include "iot_clock.h"
|
|
#include "dbg_io.h"
|
|
|
|
#include "iot_errno_api.h"
|
|
|
|
#include "dtest_printf.h"
|
|
|
|
#define DTEST_SPINLOCK_CORE0_USE_SPINLOCK 1
|
|
|
|
#define DTEST_SPINLOCK_RAM_ADDR_CNT AHB_RAM0_BASEADDR
|
|
#define DTEST_SPINLOCK_RAM_ADDR_DATA (AHB_RAM0_BASEADDR + 3 * 4)
|
|
#define DTEST_SPINLOCK_TEST_NUM SPINLOCK_INDEX_0
|
|
#define DTEST_SPINLOCK_TEST_CNT 10000
|
|
#define DTEST_SPINLOCK_TIME_DELAY 100
|
|
|
|
#define DTEST_SPINLOCK_CASE_MUTEX (1 << 0)
|
|
|
|
extern void _core_start(void);
|
|
|
|
void dtest_spinlock_core12_main()
|
|
{
|
|
uint8_t cpu = cpu_get_mhartid();
|
|
|
|
gp_timer_init();
|
|
gp_timer_set(0, 0xffffffff, 0);
|
|
gp_timer_start(0);
|
|
|
|
while (1) {
|
|
iot_spinlock_lock(DTEST_SPINLOCK_TEST_NUM, cpu);
|
|
// iot_printf("cpu:%d get spinlock\n", cpu);
|
|
|
|
*(uint32_t*)(DTEST_SPINLOCK_RAM_ADDR_DATA) = (1 << cpu);
|
|
*(uint32_t*)(DTEST_SPINLOCK_RAM_ADDR_CNT + cpu * 4) += 1;
|
|
iot_delay_us(DTEST_SPINLOCK_TIME_DELAY);
|
|
|
|
iot_spinlock_unlock(DTEST_SPINLOCK_TEST_NUM, cpu);
|
|
}
|
|
}
|
|
|
|
static uint32_t dtest_spinlock_multicore_mutex_test()
|
|
{
|
|
uint8_t i;
|
|
uint32_t data, cnt_0 = 0, cnt_1 = 0, cnt_2 = 0;
|
|
uint8_t cpu = cpu_get_mhartid();
|
|
uint32_t time_start, time_end, time_delta;
|
|
|
|
dcase_start("spinlock multicore access test\n");
|
|
|
|
dprintf("set ram data to 0\n");
|
|
for (i = 0; i < 3; i++) {
|
|
*(uint32_t *)(DTEST_SPINLOCK_RAM_ADDR_CNT + i * 4) = 0;
|
|
}
|
|
|
|
dprintf("enable core1 and core2\n");
|
|
time_start = gp_timer_get_current_val(0);
|
|
ahb_core1_set_start((uint32_t)_core_start);
|
|
ahb_core1_enable();
|
|
ahb_core1_reset();
|
|
ahb_core2_set_start((uint32_t)_core_start);
|
|
ahb_core2_enable();
|
|
ahb_core2_reset();
|
|
|
|
/* core0 delay sometime to make sure get spinlock last */
|
|
iot_delay_us(DTEST_SPINLOCK_TIME_DELAY);
|
|
|
|
while (1) {
|
|
#if DTEST_SPINLOCK_CORE0_USE_SPINLOCK
|
|
iot_spinlock_lock(DTEST_SPINLOCK_TEST_NUM, cpu);
|
|
// iot_printf("cpu:%d get spinlock\n", cpu);
|
|
*(uint32_t*)(DTEST_SPINLOCK_RAM_ADDR_DATA) = (1 << cpu);
|
|
*(uint32_t*)(DTEST_SPINLOCK_RAM_ADDR_CNT) += 1;
|
|
iot_delay_us(DTEST_SPINLOCK_TIME_DELAY);
|
|
#endif
|
|
data = *(uint32_t*)(DTEST_SPINLOCK_RAM_ADDR_DATA);
|
|
cnt_0 = *(uint32_t*)(DTEST_SPINLOCK_RAM_ADDR_CNT);
|
|
cnt_1 = *(uint32_t*)(DTEST_SPINLOCK_RAM_ADDR_CNT + 4);
|
|
cnt_2 = *(uint32_t*)(DTEST_SPINLOCK_RAM_ADDR_CNT + 8);
|
|
|
|
if (data != 0x1 && data != 0x2 && data != 0x4) {
|
|
dprintf("ram access conflict, err data:0x%08x\n", data);
|
|
i = 0;
|
|
break;
|
|
}
|
|
|
|
if (cnt_0 + cnt_1 + cnt_2 >= DTEST_SPINLOCK_TEST_CNT) {
|
|
dprintf("execution complete cnt:%d, cpu0:%d, cpu1:%d, cpu2:%d\n",
|
|
DTEST_SPINLOCK_TEST_CNT, cnt_0, cnt_1, cnt_2);
|
|
break;
|
|
}
|
|
#if DTEST_SPINLOCK_CORE0_USE_SPINLOCK
|
|
iot_spinlock_unlock(DTEST_SPINLOCK_TEST_NUM, cpu);
|
|
#endif
|
|
}
|
|
|
|
ahb_core1_disable();
|
|
ahb_core1_reset();
|
|
ahb_core2_disable();
|
|
ahb_core2_reset();
|
|
|
|
time_end = gp_timer_get_current_val(0);
|
|
time_delta = (time_end >= time_start) ? (time_end - time_start) :
|
|
(0xffffffff - time_start + time_start);
|
|
dprintf("time start:%d, end:%d, delta:%d\n", time_start, time_end, time_delta);
|
|
|
|
if (i == 0) {
|
|
dcase_failed();
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
dcase_success();
|
|
return ERR_OK;
|
|
}
|
|
|
|
static void dtest_spinlock_main()
|
|
{
|
|
uint32_t case_group = 0, failed_cnt = 0;
|
|
|
|
dbg_uart_init();
|
|
|
|
gp_timer_init();
|
|
gp_timer_set(0, 0xffffffff, 0);
|
|
gp_timer_start(0);
|
|
|
|
dconfig();
|
|
dstart();
|
|
dversion();
|
|
|
|
if (dtest_get_case_group(&case_group) < 0) {
|
|
case_group = 0xffffffff;
|
|
}
|
|
dprintf("get case group:0x%08X\n", case_group);
|
|
|
|
iot_spinlock_init();
|
|
|
|
if (case_group & DTEST_SPINLOCK_CASE_MUTEX) {
|
|
if (dtest_spinlock_multicore_mutex_test()) {
|
|
failed_cnt++;
|
|
}
|
|
}
|
|
|
|
if (failed_cnt) {
|
|
dprintf("spinlock dtest failed\n");
|
|
} else {
|
|
dprintf("spinlock dtest succeed\n");
|
|
}
|
|
|
|
dend();
|
|
|
|
return;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
dtest_spinlock_main();
|
|
return 0;
|
|
}
|