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