1a551c94aSIdo Barnea/*-
2a551c94aSIdo Barnea *   BSD LICENSE
3a551c94aSIdo Barnea *
4a551c94aSIdo Barnea *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5a551c94aSIdo Barnea *   All rights reserved.
6a551c94aSIdo Barnea *
7a551c94aSIdo Barnea *   Redistribution and use in source and binary forms, with or without
8a551c94aSIdo Barnea *   modification, are permitted provided that the following conditions
9a551c94aSIdo Barnea *   are met:
10a551c94aSIdo Barnea *
11a551c94aSIdo Barnea *     * Redistributions of source code must retain the above copyright
12a551c94aSIdo Barnea *       notice, this list of conditions and the following disclaimer.
13a551c94aSIdo Barnea *     * Redistributions in binary form must reproduce the above copyright
14a551c94aSIdo Barnea *       notice, this list of conditions and the following disclaimer in
15a551c94aSIdo Barnea *       the documentation and/or other materials provided with the
16a551c94aSIdo Barnea *       distribution.
17a551c94aSIdo Barnea *     * Neither the name of Intel Corporation nor the names of its
18a551c94aSIdo Barnea *       contributors may be used to endorse or promote products derived
19a551c94aSIdo Barnea *       from this software without specific prior written permission.
20a551c94aSIdo Barnea *
21a551c94aSIdo Barnea *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22a551c94aSIdo Barnea *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23a551c94aSIdo Barnea *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24a551c94aSIdo Barnea *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25a551c94aSIdo Barnea *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26a551c94aSIdo Barnea *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27a551c94aSIdo Barnea *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28a551c94aSIdo Barnea *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29a551c94aSIdo Barnea *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30a551c94aSIdo Barnea *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31a551c94aSIdo Barnea *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32a551c94aSIdo Barnea */
33a551c94aSIdo Barnea
34a551c94aSIdo Barnea#include <string.h>
35a551c94aSIdo Barnea#include <stdio.h>
36a551c94aSIdo Barnea#include <unistd.h>
37a551c94aSIdo Barnea#include <inttypes.h>
38a551c94aSIdo Barnea#include <sys/types.h>
39a551c94aSIdo Barnea#include <errno.h>
40a551c94aSIdo Barnea
41a551c94aSIdo Barnea#include <rte_common.h>
42a551c94aSIdo Barnea#include <rte_log.h>
43a551c94aSIdo Barnea#include <rte_cycles.h>
44a551c94aSIdo Barnea
45a551c94aSIdo Barnea#include "eal_private.h"
46a551c94aSIdo Barnea
47a551c94aSIdo Barnea/* The frequency of the RDTSC timer resolution */
48a551c94aSIdo Barneastatic uint64_t eal_tsc_resolution_hz;
49a551c94aSIdo Barnea
509ca4a157SIdo Barnea/* Pointer to user delay function */
519ca4a157SIdo Barneavoid (*rte_delay_us)(unsigned int) = NULL;
529ca4a157SIdo Barnea
53a551c94aSIdo Barneavoid
549ca4a157SIdo Barnearte_delay_us_block(unsigned int us)
55a551c94aSIdo Barnea{
56a551c94aSIdo Barnea	const uint64_t start = rte_get_timer_cycles();
57a551c94aSIdo Barnea	const uint64_t ticks = (uint64_t)us * rte_get_timer_hz() / 1E6;
58a551c94aSIdo Barnea	while ((rte_get_timer_cycles() - start) < ticks)
59a551c94aSIdo Barnea		rte_pause();
60a551c94aSIdo Barnea}
61a551c94aSIdo Barnea
62a551c94aSIdo Barneauint64_t
63a551c94aSIdo Barnearte_get_tsc_hz(void)
64a551c94aSIdo Barnea{
65a551c94aSIdo Barnea	return eal_tsc_resolution_hz;
66a551c94aSIdo Barnea}
67a551c94aSIdo Barnea
68a551c94aSIdo Barneastatic uint64_t
69a551c94aSIdo Barneaestimate_tsc_freq(void)
70a551c94aSIdo Barnea{
71a551c94aSIdo Barnea	RTE_LOG(WARNING, EAL, "WARNING: TSC frequency estimated roughly"
72a551c94aSIdo Barnea		" - clock timings may be less accurate.\n");
73a551c94aSIdo Barnea	/* assume that the sleep(1) will sleep for 1 second */
74a551c94aSIdo Barnea	uint64_t start = rte_rdtsc();
75a551c94aSIdo Barnea	sleep(1);
76a551c94aSIdo Barnea	return rte_rdtsc() - start;
77a551c94aSIdo Barnea}
78a551c94aSIdo Barnea
79a551c94aSIdo Barneavoid
80a551c94aSIdo Barneaset_tsc_freq(void)
81a551c94aSIdo Barnea{
82a551c94aSIdo Barnea	uint64_t freq = get_tsc_freq();
83a551c94aSIdo Barnea
84a551c94aSIdo Barnea	if (!freq)
85a551c94aSIdo Barnea		freq = estimate_tsc_freq();
86a551c94aSIdo Barnea
87a551c94aSIdo Barnea	RTE_LOG(DEBUG, EAL, "TSC frequency is ~%" PRIu64 " KHz\n", freq / 1000);
88a551c94aSIdo Barnea	eal_tsc_resolution_hz = freq;
89a551c94aSIdo Barnea}
909ca4a157SIdo Barnea
919ca4a157SIdo Barneavoid rte_delay_us_callback_register(void (*userfunc)(unsigned int))
929ca4a157SIdo Barnea{
939ca4a157SIdo Barnea	rte_delay_us = userfunc;
949ca4a157SIdo Barnea}
959ca4a157SIdo Barnea
969ca4a157SIdo Barneastatic void __attribute__((constructor))
979ca4a157SIdo Barnearte_timer_init(void)
989ca4a157SIdo Barnea{
999ca4a157SIdo Barnea	/* set rte_delay_us_block as a delay function */
1009ca4a157SIdo Barnea	rte_delay_us_callback_register(rte_delay_us_block);
1019ca4a157SIdo Barnea}
102