1use crate::{CounterInterface, TimerInterface};
9use arm_sysregs::el0::{
10 accessors::{
11 read_cntfrq_el0, read_cntp_ctl_el0, read_cntp_cval_el0, read_cntp_tval_el0,
12 read_cntpct_el0, read_cntv_ctl_el0, read_cntv_cval_el0, read_cntv_tval_el0,
13 read_cntvct_el0, write_cntp_ctl_el0, write_cntp_cval_el0, write_cntp_tval_el0,
14 write_cntv_ctl_el0, write_cntv_cval_el0, write_cntv_tval_el0,
15 },
16 registers::{CntpCtlEl0, CntpCvalEl0, CntpTvalEl0, CntvCtlEl0, CntvCvalEl0, CntvTvalEl0},
17};
18#[cfg(feature = "el1")]
19use arm_sysregs::el1::{
20 accessors::{
21 read_cntps_ctl_el1, read_cntps_cval_el1, read_cntps_tval_el1, write_cntps_ctl_el1,
22 write_cntps_cval_el1, write_cntps_tval_el1,
23 },
24 registers::{CntpsCtlEl1, CntpsCvalEl1, CntpsTvalEl1},
25};
26#[cfg(feature = "el2")]
27use arm_sysregs::el2::{
28 accessors::{
29 read_cnthp_ctl_el2, read_cnthp_cval_el2, read_cnthp_tval_el2, read_cnthps_ctl_el2,
30 read_cnthps_cval_el2, read_cnthps_tval_el2, read_cnthv_ctl_el2, read_cnthv_cval_el2,
31 read_cnthv_tval_el2, read_cnthvs_ctl_el2, read_cnthvs_cval_el2, read_cnthvs_tval_el2,
32 write_cnthp_ctl_el2, write_cnthp_cval_el2, write_cnthp_tval_el2, write_cnthps_ctl_el2,
33 write_cnthps_cval_el2, write_cnthps_tval_el2, write_cnthv_ctl_el2, write_cnthv_cval_el2,
34 write_cnthv_tval_el2, write_cnthvs_ctl_el2, write_cnthvs_cval_el2, write_cnthvs_tval_el2,
35 },
36 registers::{
37 CnthpCtlEl2, CnthpCvalEl2, CnthpTvalEl2, CnthpsCtlEl2, CnthpsCvalEl2, CnthpsTvalEl2,
38 CnthvCtlEl2, CnthvCvalEl2, CnthvTvalEl2, CnthvsCtlEl2, CnthvsCvalEl2, CnthvsTvalEl2,
39 },
40};
41
42#[cfg(feature = "el1")]
46pub struct PhysicalSecureTimer(());
47
48#[cfg(feature = "el1")]
49impl PhysicalSecureTimer {
50 pub const unsafe fn new() -> Self {
57 Self(())
58 }
59}
60
61#[cfg(feature = "el1")]
62impl TimerInterface for PhysicalSecureTimer {
63 fn enable(&mut self) {
64 let control = read_cntps_ctl_el1();
65 write_cntps_ctl_el1(control | CntpsCtlEl1::ENABLE);
66 }
67
68 fn frequency(&self) -> u32 {
69 read_cntfrq_el0().clockfreq()
70 }
71
72 fn timer_value(&self) -> i32 {
73 read_cntps_tval_el1().timervalue() as i32
74 }
75
76 fn enable_interrupt(&mut self, enabled: bool) {
77 let mut control = read_cntps_ctl_el1();
78 control.set(CntpsCtlEl1::IMASK, !enabled);
79
80 write_cntps_ctl_el1(control);
81 }
82
83 fn compare_value(&self) -> u64 {
84 read_cntps_cval_el1().comparevalue()
85 }
86
87 fn set_timer_value(&mut self, timer_value: i32) {
88 write_cntps_tval_el1(CntpsTvalEl1::empty().with_timervalue(timer_value));
89 }
90
91 fn set_compare_value(&mut self, compare_value: u64) {
92 write_cntps_cval_el1(CntpsCvalEl1::empty().with_comparevalue(compare_value));
93 }
94}
95
96#[cfg(feature = "el2")]
100pub struct HypervisorPhysicalTimer(());
101
102#[cfg(feature = "el2")]
103impl HypervisorPhysicalTimer {
104 pub const unsafe fn new() -> Self {
111 Self(())
112 }
113}
114
115#[cfg(feature = "el2")]
116impl TimerInterface for HypervisorPhysicalTimer {
117 fn enable(&mut self) {
118 let control = read_cnthp_ctl_el2();
119 write_cnthp_ctl_el2(control | CnthpCtlEl2::ENABLE);
120 }
121
122 fn frequency(&self) -> u32 {
123 read_cntfrq_el0().clockfreq()
124 }
125
126 fn timer_value(&self) -> i32 {
127 read_cnthp_tval_el2().timervalue() as i32
128 }
129
130 fn enable_interrupt(&mut self, enabled: bool) {
131 let mut control = read_cnthp_ctl_el2();
132 control.set(CnthpCtlEl2::IMASK, !enabled);
133
134 write_cnthp_ctl_el2(control);
135 }
136
137 fn compare_value(&self) -> u64 {
138 read_cnthp_cval_el2().comparevalue()
139 }
140
141 fn set_timer_value(&mut self, timer_value: i32) {
142 write_cnthp_tval_el2(CnthpTvalEl2::empty().with_timervalue(timer_value));
143 }
144
145 fn set_compare_value(&mut self, compare_value: u64) {
146 write_cnthp_cval_el2(CnthpCvalEl2::empty().with_comparevalue(compare_value));
147 }
148}
149
150#[cfg(feature = "el2")]
154pub struct SecureEl2PhysicalTimer(());
155
156#[cfg(feature = "el2")]
157impl SecureEl2PhysicalTimer {
158 pub const unsafe fn new() -> Self {
165 Self(())
166 }
167}
168
169#[cfg(feature = "el2")]
170impl TimerInterface for SecureEl2PhysicalTimer {
171 fn enable(&mut self) {
172 let control = read_cnthps_ctl_el2();
173 write_cnthps_ctl_el2(control | CnthpsCtlEl2::ENABLE);
174 }
175
176 fn frequency(&self) -> u32 {
177 read_cntfrq_el0().clockfreq()
178 }
179
180 fn timer_value(&self) -> i32 {
181 read_cnthps_tval_el2().timervalue() as i32
182 }
183
184 fn enable_interrupt(&mut self, enabled: bool) {
185 let mut control = read_cnthps_ctl_el2();
186 control.set(CnthpsCtlEl2::IMASK, !enabled);
187
188 write_cnthps_ctl_el2(control);
189 }
190
191 fn compare_value(&self) -> u64 {
192 read_cnthps_cval_el2().comparevalue()
193 }
194
195 fn set_timer_value(&mut self, timer_value: i32) {
196 write_cnthps_tval_el2(CnthpsTvalEl2::empty().with_timervalue(timer_value));
197 }
198
199 fn set_compare_value(&mut self, compare_value: u64) {
200 write_cnthps_cval_el2(CnthpsCvalEl2::empty().with_comparevalue(compare_value));
201 }
202}
203
204#[cfg(feature = "el2")]
208pub struct El2VirtualTimer(());
209
210#[cfg(feature = "el2")]
211impl El2VirtualTimer {
212 pub const unsafe fn new() -> Self {
219 Self(())
220 }
221}
222
223#[cfg(feature = "el2")]
224impl TimerInterface for El2VirtualTimer {
225 fn enable(&mut self) {
226 let control = read_cnthv_ctl_el2();
227 write_cnthv_ctl_el2(control | CnthvCtlEl2::ENABLE);
228 }
229
230 fn frequency(&self) -> u32 {
231 read_cntfrq_el0().clockfreq()
232 }
233
234 fn timer_value(&self) -> i32 {
235 read_cnthv_tval_el2().timervalue() as i32
236 }
237
238 fn enable_interrupt(&mut self, enabled: bool) {
239 let mut control = read_cnthv_ctl_el2();
240 control.set(CnthvCtlEl2::IMASK, !enabled);
241
242 write_cnthv_ctl_el2(control);
243 }
244
245 fn compare_value(&self) -> u64 {
246 read_cnthv_cval_el2().comparevalue()
247 }
248
249 fn set_timer_value(&mut self, timer_value: i32) {
250 write_cnthv_tval_el2(CnthvTvalEl2::empty().with_timervalue(timer_value));
251 }
252
253 fn set_compare_value(&mut self, compare_value: u64) {
254 write_cnthv_cval_el2(CnthvCvalEl2::empty().with_comparevalue(compare_value));
255 }
256}
257
258#[cfg(feature = "el2")]
262pub struct SecureEl2VirtualTimer(());
263
264#[cfg(feature = "el2")]
265impl SecureEl2VirtualTimer {
266 pub const unsafe fn new() -> Self {
273 Self(())
274 }
275}
276
277#[cfg(feature = "el2")]
278impl TimerInterface for SecureEl2VirtualTimer {
279 fn enable(&mut self) {
280 let control = read_cnthvs_ctl_el2();
281 write_cnthvs_ctl_el2(control | CnthvsCtlEl2::ENABLE);
282 }
283
284 fn frequency(&self) -> u32 {
285 read_cntfrq_el0().clockfreq()
286 }
287
288 fn timer_value(&self) -> i32 {
289 read_cnthvs_tval_el2().timervalue() as i32
290 }
291
292 fn enable_interrupt(&mut self, enabled: bool) {
293 let mut control = read_cnthvs_ctl_el2();
294 control.set(CnthvsCtlEl2::IMASK, !enabled);
295
296 write_cnthvs_ctl_el2(control);
297 }
298
299 fn compare_value(&self) -> u64 {
300 read_cnthvs_cval_el2().comparevalue()
301 }
302
303 fn set_timer_value(&mut self, timer_value: i32) {
304 write_cnthvs_tval_el2(CnthvsTvalEl2::empty().with_timervalue(timer_value));
305 }
306
307 fn set_compare_value(&mut self, compare_value: u64) {
308 write_cnthvs_cval_el2(CnthvsCvalEl2::empty().with_comparevalue(compare_value));
309 }
310}
311
312pub struct PhysicalTimer(());
316
317impl PhysicalTimer {
318 pub const unsafe fn new() -> Self {
325 Self(())
326 }
327}
328
329impl TimerInterface for PhysicalTimer {
330 fn enable(&mut self) {
331 let control = read_cntp_ctl_el0();
332 write_cntp_ctl_el0(control | CntpCtlEl0::ENABLE);
333 }
334
335 fn frequency(&self) -> u32 {
336 read_cntfrq_el0().clockfreq()
337 }
338
339 fn timer_value(&self) -> i32 {
340 read_cntp_tval_el0().timervalue() as i32
341 }
342
343 fn enable_interrupt(&mut self, enabled: bool) {
344 let mut control = read_cntp_ctl_el0();
345 control.set(CntpCtlEl0::IMASK, !enabled);
346
347 write_cntp_ctl_el0(control);
348 }
349
350 fn compare_value(&self) -> u64 {
351 read_cntp_cval_el0().comparevalue()
352 }
353
354 fn set_timer_value(&mut self, timer_value: i32) {
355 write_cntp_tval_el0(CntpTvalEl0::empty().with_timervalue(timer_value));
356 }
357
358 fn set_compare_value(&mut self, compare_value: u64) {
359 write_cntp_cval_el0(CntpCvalEl0::empty().with_comparevalue(compare_value));
360 }
361}
362
363pub struct VirtualTimer(());
367
368impl VirtualTimer {
369 pub const unsafe fn new() -> Self {
376 Self(())
377 }
378}
379
380impl TimerInterface for VirtualTimer {
381 fn enable(&mut self) {
382 let control = read_cntv_ctl_el0();
383 write_cntv_ctl_el0(control | CntvCtlEl0::ENABLE);
384 }
385
386 fn frequency(&self) -> u32 {
387 read_cntfrq_el0().clockfreq()
388 }
389
390 fn timer_value(&self) -> i32 {
391 read_cntv_tval_el0().timervalue() as i32
392 }
393
394 fn enable_interrupt(&mut self, enabled: bool) {
395 let mut control = read_cntv_ctl_el0();
396 control.set(CntvCtlEl0::IMASK, !enabled);
397
398 write_cntv_ctl_el0(control);
399 }
400
401 fn compare_value(&self) -> u64 {
402 read_cntv_cval_el0().comparevalue()
403 }
404
405 fn set_timer_value(&mut self, timer_value: i32) {
406 write_cntv_tval_el0(CntvTvalEl0::empty().with_timervalue(timer_value));
407 }
408
409 fn set_compare_value(&mut self, compare_value: u64) {
410 write_cntv_cval_el0(CntvCvalEl0::empty().with_comparevalue(compare_value));
411 }
412}
413
414pub struct PhysicalCounter;
416
417impl CounterInterface for PhysicalCounter {
418 fn counter_value(&self) -> u64 {
419 read_cntpct_el0().physicalcount()
420 }
421
422 fn frequency(&self) -> u32 {
423 read_cntfrq_el0().clockfreq()
424 }
425}
426
427pub struct VirtualCounter;
429
430impl CounterInterface for VirtualCounter {
431 fn counter_value(&self) -> u64 {
432 read_cntvct_el0().virtualcount()
433 }
434
435 fn frequency(&self) -> u32 {
436 read_cntfrq_el0().clockfreq()
437 }
438}