The Pedigree Project 0.1
GenericTimer.h
1#ifndef PEDIGREE_MACH_VIRT_GENERIC_TIMER_H
2#define PEDIGREE_MACH_VIRT_GENERIC_TIMER_H
3
4#include <config.h>
5#include <stdint.h>
6
7namespace VirtGenericTimer {
8inline uint64_t count() {
9#if ARMV7
10 uint32_t low, high;
11 asm volatile("mrrc p15, 1, %0, %1, c14" : "=r"(low), "=r"(high));
12 return (uint64_t(high) << 32) | low;
13#else
14 uint64_t value;
15 asm volatile("mrs %0, cntvct_el0" : "=r"(value));
16 return value;
17#endif
18}
19
20inline uint32_t frequency() {
21#if ARMV7
22 uint32_t value;
23 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r"(value));
24 return value;
25#else
26 uint64_t value;
27 asm volatile("mrs %0, cntfrq_el0" : "=r"(value));
28 return static_cast<uint32_t>(value);
29#endif
30}
31
32inline void virtualControl(uint32_t value) {
33#if ARMV7
34 asm volatile("mcr p15, 0, %0, c14, c3, 1\n\tisb" : : "r"(value) : "memory");
35#else
36 asm volatile("msr cntv_ctl_el0, %0\n\tisb" : : "r"(uint64_t(value)) : "memory");
37#endif
38}
39
40inline void physicalControl(uint32_t value) {
41#if ARMV7
42 asm volatile("mcr p15, 0, %0, c14, c2, 1\n\tisb" : : "r"(value) : "memory");
43#else
44 asm volatile("msr cntp_ctl_el0, %0\n\tisb" : : "r"(uint64_t(value)) : "memory");
45#endif
46}
47
48inline void setVirtualTimer(uint32_t ticks) {
49#if ARMV7
50 const uint32_t enabled = 1;
51 asm volatile(
52 "mcr p15, 0, %0, c14, c3, 0\n\t"
53 "mcr p15, 0, %1, c14, c3, 1\n\tisb"
54 :
55 : "r"(ticks), "r"(enabled)
56 : "memory");
57#else
58 asm volatile("msr cntv_tval_el0, %0\n\tmsr cntv_ctl_el0, %1\n\tisb"
59 :
60 : "r"(uint64_t(ticks)), "r"(uint64_t(1))
61 : "memory");
62#endif
63}
64
65inline void setPhysicalTimer(uint32_t ticks) {
66#if ARMV7
67 const uint32_t enabled = 1;
68 asm volatile(
69 "mcr p15, 0, %0, c14, c2, 0\n\t"
70 "mcr p15, 0, %1, c14, c2, 1\n\tisb"
71 :
72 : "r"(ticks), "r"(enabled)
73 : "memory");
74#else
75 asm volatile("msr cntp_tval_el0, %0\n\tmsr cntp_ctl_el0, %1\n\tisb"
76 :
77 : "r"(uint64_t(ticks)), "r"(uint64_t(1))
78 : "memory");
79#endif
80}
81} // namespace VirtGenericTimer
82
83#endif