Xenomai  3.0-rc6
tsc.h
1 /*
2  * Copyright (C) 2009 Philippe Gerum <rpm@xenomai.org>.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18 #ifndef _LIB_COBALT_NIOS2_TSC_H
19 #define _LIB_COBALT_NIOS2_TSC_H
20 
21 extern volatile void *__cobalt_nios2_hrclock;
22 
23 static inline unsigned long long cobalt_read_tsc(void)
24 {
25  volatile unsigned short *hrclock;
26  int64_t t0, t1;
27 
28  hrclock = __cobalt_nios2_hrclock;
29 
30 #define hrclock_wrsnap(reg, val) \
31  (*(hrclock + (12 + ((reg) * 2)))) = (val)
32 
33 #define hrclock_rdsnap(reg) \
34  (int64_t)(*(hrclock + (12 + ((reg) * 2)))) << (reg * 16)
35 
36 #define hrclock_peeksnap() \
37  ({ \
38  int64_t __snap; \
39  __snap = hrclock_rdsnap(3) | hrclock_rdsnap(2) | \
40  hrclock_rdsnap(1) | hrclock_rdsnap(0); \
41  __snap; \
42  })
43 
44 #define hrclock_getsnap() \
45  ({ \
46  hrclock_wrsnap(0, 0); \
47  hrclock_peeksnap(); \
48  })
49 
50  /*
51  * We compete with both the kernel and userland applications
52  * which may request a snapshot as well, but we don't have any
53  * simple mutual exclusion mechanism at hand to avoid
54  * races. In order to keep the overhead of reading the hrclock
55  * from userland low, we make sure to read two consecutive
56  * coherent snapshots. In case both readings do not match, we
57  * have to request a fresh snapshot anew, since it means that
58  * we have been preempted in the middle of the operation.
59  */
60  do {
61  t0 = hrclock_getsnap(); /* Request snapshot and read it */
62  __asm__ __volatile__("": : :"memory");
63  t1 = hrclock_peeksnap(); /* Confirm first reading */
64  } while (t0 != t1);
65 
66 #undef hrclock_getsnap
67 #undef hrclock_rdsnap
68 #undef hrclock_wrsnap
69 
70  return ~t0;
71 }
72 
73 #endif /* !_LIB_COBALT_NIOS2_TSC_H */