1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2015 Cavium, Inc 3 * Copyright(c) 2022 StarFive 4 * Copyright(c) 2022 SiFive 5 * Copyright(c) 2022 Semihalf 6 */ 7 8 #include <stdio.h> 9 10 #include "eal_private.h" 11 #include "rte_byteorder.h" 12 #include "rte_cycles.h" 13 #include "rte_log.h" 14 15 /** Read generic counter frequency */ 16 static uint64_t 17 __rte_riscv_timefrq(void) 18 { 19 #define TIMEBASE_FREQ_SIZE 8 20 if (RTE_RISCV_TIME_FREQ > 0) 21 return RTE_RISCV_TIME_FREQ; 22 uint8_t buf[TIMEBASE_FREQ_SIZE]; 23 ssize_t cnt; 24 FILE *file; 25 26 file = fopen("/proc/device-tree/cpus/timebase-frequency", "rb"); 27 if (!file) 28 goto fail; 29 30 cnt = fread(buf, 1, TIMEBASE_FREQ_SIZE, file); 31 fclose(file); 32 switch (cnt) { 33 case 8: 34 return rte_be_to_cpu_64(*(uint64_t *)buf); 35 case 4: 36 return rte_be_to_cpu_32(*(uint32_t *)buf); 37 default: 38 break; 39 } 40 fail: 41 EAL_LOG(WARNING, "Unable to read timebase-frequency from FDT."); 42 return 0; 43 } 44 45 uint64_t 46 get_tsc_freq_arch(void) 47 { 48 EAL_LOG(NOTICE, "TSC using RISC-V %s.", 49 RTE_RISCV_RDTSC_USE_HPM ? "rdcycle" : "rdtime"); 50 if (!RTE_RISCV_RDTSC_USE_HPM) 51 return __rte_riscv_timefrq(); 52 #define CYC_PER_1MHZ 1E6 53 /* 54 * Use real time clock to estimate current cycle frequency 55 */ 56 uint64_t ticks, frq; 57 uint64_t start_ticks, cur_ticks; 58 uint64_t start_cycle, end_cycle; 59 60 /* Do not proceed unless clock frequency can be obtained. */ 61 frq = __rte_riscv_timefrq(); 62 if (!frq) 63 return 0; 64 65 /* Number of ticks for 1/10 second */ 66 ticks = frq / 10; 67 68 start_ticks = __rte_riscv_rdtime_precise(); 69 start_cycle = rte_rdtsc_precise(); 70 do { 71 cur_ticks = __rte_riscv_rdtime(); 72 } while ((cur_ticks - start_ticks) < ticks); 73 end_cycle = rte_rdtsc_precise(); 74 75 /* Adjust the cycles to next 1Mhz */ 76 return RTE_ALIGN_MUL_CEIL((end_cycle - start_cycle) * 10, CYC_PER_1MHZ); 77 } 78