1#ifndef PEDIGREE_MACH_VIRT_GENERIC_TIMER_H
2#define PEDIGREE_MACH_VIRT_GENERIC_TIMER_H
7namespace VirtGenericTimer {
8inline uint64_t count() {
11 asm volatile(
"mrrc p15, 1, %0, %1, c14" :
"=r"(low),
"=r"(high));
12 return (uint64_t(high) << 32) | low;
15 asm volatile(
"mrs %0, cntvct_el0" :
"=r"(value));
20inline uint32_t frequency() {
23 asm volatile(
"mrc p15, 0, %0, c14, c0, 0" :
"=r"(value));
27 asm volatile(
"mrs %0, cntfrq_el0" :
"=r"(value));
28 return static_cast<uint32_t
>(value);
32inline void virtualControl(uint32_t value) {
34 asm volatile(
"mcr p15, 0, %0, c14, c3, 1\n\tisb" : :
"r"(value) :
"memory");
36 asm volatile(
"msr cntv_ctl_el0, %0\n\tisb" : :
"r"(uint64_t(value)) :
"memory");
40inline void physicalControl(uint32_t value) {
42 asm volatile(
"mcr p15, 0, %0, c14, c2, 1\n\tisb" : :
"r"(value) :
"memory");
44 asm volatile(
"msr cntp_ctl_el0, %0\n\tisb" : :
"r"(uint64_t(value)) :
"memory");
48inline void setVirtualTimer(uint32_t ticks) {
50 const uint32_t enabled = 1;
52 "mcr p15, 0, %0, c14, c3, 0\n\t"
53 "mcr p15, 0, %1, c14, c3, 1\n\tisb"
55 :
"r"(ticks),
"r"(enabled)
58 asm volatile(
"msr cntv_tval_el0, %0\n\tmsr cntv_ctl_el0, %1\n\tisb"
60 :
"r"(uint64_t(ticks)),
"r"(uint64_t(1))
65inline void setPhysicalTimer(uint32_t ticks) {
67 const uint32_t enabled = 1;
69 "mcr p15, 0, %0, c14, c2, 0\n\t"
70 "mcr p15, 0, %1, c14, c2, 1\n\tisb"
72 :
"r"(ticks),
"r"(enabled)
75 asm volatile(
"msr cntp_tval_el0, %0\n\tmsr cntp_ctl_el0, %1\n\tisb"
77 :
"r"(uint64_t(ticks)),
"r"(uint64_t(1))