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