1 /* 2 * Copyright (c) 2020 Intel Corporation. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include <zephyr/arch/x86/arch.h> 8 #include <zephyr/kernel.h> 9 #include <zephyr/sys_clock.h> 10 #include <zephyr/timing/timing.h> 11 #include <zephyr/app_memory/app_memdomain.h> 12 K_APP_BMEM(z_libc_partition)13K_APP_BMEM(z_libc_partition) static uint64_t tsc_freq; 14 15 void arch_timing_x86_init(void) 16 { 17 uint32_t cyc_start, cyc_end; 18 uint64_t tsc_start, tsc_end; 19 uint64_t cyc_freq = sys_clock_hw_cycles_per_sec(); 20 uint64_t dcyc, dtsc; 21 22 do { 23 cyc_start = k_cycle_get_32(); 24 tsc_start = z_tsc_read(); 25 26 k_busy_wait(10 * USEC_PER_MSEC); 27 28 cyc_end = k_cycle_get_32(); 29 tsc_end = z_tsc_read(); 30 31 /* 32 * cycles are in 32-bit, and delta must be 33 * calculated in 32-bit precision. Or it would be 34 * wrapping around in 64-bit. 35 */ 36 dcyc = (uint32_t)cyc_end - (uint32_t)cyc_start; 37 dtsc = tsc_end - tsc_start; 38 } while ((dcyc == 0) || (dtsc == 0)); 39 40 tsc_freq = (cyc_freq * dtsc) / dcyc; 41 } 42 arch_timing_x86_freq_get(void)43uint64_t arch_timing_x86_freq_get(void) 44 { 45 return tsc_freq; 46 } 47 arch_timing_init(void)48void arch_timing_init(void) 49 { 50 arch_timing_x86_init(); 51 } 52 arch_timing_start(void)53void arch_timing_start(void) 54 { 55 } 56 arch_timing_stop(void)57void arch_timing_stop(void) 58 { 59 } 60 arch_timing_counter_get(void)61timing_t arch_timing_counter_get(void) 62 { 63 return z_tsc_read(); 64 } 65 arch_timing_cycles_get(volatile timing_t * const start,volatile timing_t * const end)66uint64_t arch_timing_cycles_get(volatile timing_t *const start, 67 volatile timing_t *const end) 68 { 69 return (*end - *start); 70 } 71 72 arch_timing_freq_get(void)73uint64_t arch_timing_freq_get(void) 74 { 75 return arch_timing_x86_freq_get(); 76 } 77 arch_timing_cycles_to_ns(uint64_t cycles)78uint64_t arch_timing_cycles_to_ns(uint64_t cycles) 79 { 80 return ((cycles) * NSEC_PER_SEC / tsc_freq); 81 } 82 arch_timing_cycles_to_ns_avg(uint64_t cycles,uint32_t count)83uint64_t arch_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) 84 { 85 return arch_timing_cycles_to_ns(cycles) / count; 86 } 87 arch_timing_freq_get_mhz(void)88uint32_t arch_timing_freq_get_mhz(void) 89 { 90 return (uint32_t)(arch_timing_freq_get() / 1000000U); 91 } 92