14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause 24418919fSjohnjiang * Copyright(c) 2010-2014 Intel Corporation 34418919fSjohnjiang */ 44418919fSjohnjiang 54418919fSjohnjiang #include <stdio.h> 64418919fSjohnjiang #include <stdint.h> 74418919fSjohnjiang 84418919fSjohnjiang #include <rte_common.h> 94418919fSjohnjiang #include <rte_cycles.h> 104418919fSjohnjiang 114418919fSjohnjiang #include "test.h" 124418919fSjohnjiang 134418919fSjohnjiang #define N 10000 144418919fSjohnjiang 154418919fSjohnjiang /* 164418919fSjohnjiang * Cycles test 174418919fSjohnjiang * =========== 184418919fSjohnjiang * 194418919fSjohnjiang * - Loop N times and check that the timer always increments and 204418919fSjohnjiang * never decrements during this loop. 214418919fSjohnjiang * 224418919fSjohnjiang * - Wait one second using rte_usleep() and check that the increment 234418919fSjohnjiang * of cycles is correct with regard to the frequency of the timer. 244418919fSjohnjiang */ 254418919fSjohnjiang 264418919fSjohnjiang static int check_wait_one_second(void)274418919fSjohnjiangcheck_wait_one_second(void) 284418919fSjohnjiang { 294418919fSjohnjiang uint64_t cycles, prev_cycles; 304418919fSjohnjiang uint64_t hz = rte_get_timer_hz(); 314418919fSjohnjiang uint64_t max_inc = (hz / 100); /* 10 ms max between 2 reads */ 324418919fSjohnjiang 334418919fSjohnjiang /* check that waiting 1 second is precise */ 344418919fSjohnjiang prev_cycles = rte_get_timer_cycles(); 354418919fSjohnjiang rte_delay_us(1000000); 364418919fSjohnjiang cycles = rte_get_timer_cycles(); 374418919fSjohnjiang 384418919fSjohnjiang if ((uint64_t)(cycles - prev_cycles) > (hz + max_inc)) { 394418919fSjohnjiang printf("delay_us is not accurate: too long\n"); 404418919fSjohnjiang return -1; 414418919fSjohnjiang } 424418919fSjohnjiang if ((uint64_t)(cycles - prev_cycles) < (hz - max_inc)) { 434418919fSjohnjiang printf("delay_us is not accurate: too short\n"); 444418919fSjohnjiang return -1; 454418919fSjohnjiang } 464418919fSjohnjiang 474418919fSjohnjiang return 0; 484418919fSjohnjiang } 494418919fSjohnjiang 504418919fSjohnjiang static int test_cycles(void)514418919fSjohnjiangtest_cycles(void) 524418919fSjohnjiang { 534418919fSjohnjiang unsigned i; 544418919fSjohnjiang uint64_t start_cycles, cycles, prev_cycles; 554418919fSjohnjiang uint64_t hz = rte_get_timer_hz(); 564418919fSjohnjiang uint64_t max_inc = (hz / 100); /* 10 ms max between 2 reads */ 574418919fSjohnjiang 584418919fSjohnjiang /* check that the timer is always incrementing */ 594418919fSjohnjiang start_cycles = rte_get_timer_cycles(); 604418919fSjohnjiang prev_cycles = start_cycles; 614418919fSjohnjiang for (i=0; i<N; i++) { 624418919fSjohnjiang cycles = rte_get_timer_cycles(); 634418919fSjohnjiang if ((uint64_t)(cycles - prev_cycles) > max_inc) { 644418919fSjohnjiang printf("increment too high or going backwards\n"); 654418919fSjohnjiang return -1; 664418919fSjohnjiang } 674418919fSjohnjiang prev_cycles = cycles; 684418919fSjohnjiang } 694418919fSjohnjiang 704418919fSjohnjiang return check_wait_one_second(); 714418919fSjohnjiang } 724418919fSjohnjiang 734418919fSjohnjiang REGISTER_TEST_COMMAND(cycles_autotest, test_cycles); 744418919fSjohnjiang 754418919fSjohnjiang /* 764418919fSjohnjiang * One second precision test with rte_delay_us_sleep. 774418919fSjohnjiang */ 784418919fSjohnjiang 794418919fSjohnjiang static int test_delay_us_sleep(void)804418919fSjohnjiangtest_delay_us_sleep(void) 814418919fSjohnjiang { 82*0c6bd470Sfengbojiang int rv; 83*0c6bd470Sfengbojiang 844418919fSjohnjiang rte_delay_us_callback_register(rte_delay_us_sleep); 85*0c6bd470Sfengbojiang rv = check_wait_one_second(); 86*0c6bd470Sfengbojiang /* restore original delay function */ 87*0c6bd470Sfengbojiang rte_delay_us_callback_register(rte_delay_us_block); 88*0c6bd470Sfengbojiang 89*0c6bd470Sfengbojiang return rv; 904418919fSjohnjiang } 914418919fSjohnjiang 924418919fSjohnjiang REGISTER_TEST_COMMAND(delay_us_sleep_autotest, test_delay_us_sleep); 934418919fSjohnjiang 944418919fSjohnjiang /* 954418919fSjohnjiang * rte_delay_us_callback test 964418919fSjohnjiang * 974418919fSjohnjiang * - check if callback is correctly registered/unregistered 984418919fSjohnjiang * 994418919fSjohnjiang */ 1004418919fSjohnjiang 1014418919fSjohnjiang static unsigned int pattern; my_rte_delay_us(unsigned int us)1024418919fSjohnjiangstatic void my_rte_delay_us(unsigned int us) 1034418919fSjohnjiang { 1044418919fSjohnjiang pattern += us; 1054418919fSjohnjiang } 1064418919fSjohnjiang 1074418919fSjohnjiang static int test_user_delay_us(void)1084418919fSjohnjiangtest_user_delay_us(void) 1094418919fSjohnjiang { 1104418919fSjohnjiang pattern = 0; 1114418919fSjohnjiang 1124418919fSjohnjiang rte_delay_us(2); 1134418919fSjohnjiang if (pattern != 0) 1144418919fSjohnjiang return -1; 1154418919fSjohnjiang 1164418919fSjohnjiang /* register custom delay function */ 1174418919fSjohnjiang rte_delay_us_callback_register(my_rte_delay_us); 1184418919fSjohnjiang 1194418919fSjohnjiang rte_delay_us(2); 1204418919fSjohnjiang if (pattern != 2) 1214418919fSjohnjiang return -1; 1224418919fSjohnjiang 1234418919fSjohnjiang rte_delay_us(3); 1244418919fSjohnjiang if (pattern != 5) 1254418919fSjohnjiang return -1; 1264418919fSjohnjiang 1274418919fSjohnjiang /* restore original delay function */ 1284418919fSjohnjiang rte_delay_us_callback_register(rte_delay_us_block); 1294418919fSjohnjiang 1304418919fSjohnjiang rte_delay_us(3); 1314418919fSjohnjiang if (pattern != 5) 1324418919fSjohnjiang return -1; 1334418919fSjohnjiang 1344418919fSjohnjiang return 0; 1354418919fSjohnjiang } 1364418919fSjohnjiang 1374418919fSjohnjiang REGISTER_TEST_COMMAND(user_delay_us, test_user_delay_us); 138