aarch32_cpu/generic_timer/
el1.rs1use crate::register;
4
5use super::{El0PhysicalTimer, El0VirtualTimer, GenericTimer};
6
7pub struct El1PhysicalTimer(pub(crate) El0PhysicalTimer);
9
10impl El1PhysicalTimer {
11 pub unsafe fn new() -> El1PhysicalTimer {
18 unsafe { El1PhysicalTimer(El0PhysicalTimer::new()) }
19 }
20
21 pub fn el0_access_physical_counter(&mut self, access: bool) {
23 register::Cntkctl::modify(|r| {
24 r.set_el0pcten(access);
25 });
26 }
27
28 pub fn el0_access_physical_timer(&mut self, access: bool) {
30 register::Cntkctl::modify(|r| {
31 r.set_el0pten(access);
32 });
33 }
34}
35
36impl GenericTimer for El1PhysicalTimer {
37 fn frequency_hz(&self) -> u32 {
38 self.0.frequency_hz()
39 }
40
41 fn counter(&self) -> u64 {
42 self.0.counter()
43 }
44
45 fn counter_compare(&self) -> u64 {
46 self.0.counter_compare()
47 }
48
49 fn counter_compare_set(&mut self, value: u64) {
50 self.0.counter_compare_set(value)
51 }
52
53 fn countdown(&self) -> u32 {
54 self.0.countdown()
55 }
56
57 fn countdown_set(&mut self, duration_ticks: u32) {
58 self.0.countdown_set(duration_ticks)
59 }
60
61 fn enabled(&self) -> bool {
62 self.0.enabled()
63 }
64
65 fn enable(&self, enabled: bool) {
66 self.0.enable(enabled)
67 }
68
69 fn interrupt_masked(&self) -> bool {
70 self.0.interrupt_masked()
71 }
72
73 fn interrupt_mask(&mut self, mask: bool) {
74 self.0.interrupt_mask(mask)
75 }
76
77 fn interrupt_status(&self) -> bool {
78 self.0.interrupt_status()
79 }
80}
81
82pub struct El1VirtualTimer(El0VirtualTimer);
84
85impl El1VirtualTimer {
86 pub unsafe fn new() -> El1VirtualTimer {
93 unsafe { El1VirtualTimer(El0VirtualTimer::new()) }
94 }
95
96 pub fn el0_access_virtual_counter(&mut self, access: bool) {
98 register::Cntkctl::modify(|r| {
99 r.set_el0vcten(access);
100 });
101 }
102
103 pub fn el0_access_virtual_timer(&mut self, access: bool) {
105 register::Cntkctl::modify(|r| {
106 r.set_el0vten(access);
107 });
108 }
109
110 pub fn virtual_event_stream_configure(&mut self, event_config: Option<&super::EventConfig>) {
122 if let Some(event_config) = event_config {
123 register::Cntkctl::modify(|r| {
124 r.set_evnti(arbitrary_int::u4::from_u8(event_config.rate as u8));
125 r.set_evntdir(event_config.evntdir == super::EventDir::HighLow);
126 r.set_evnten(true);
127 });
128 } else {
129 register::Cntkctl::modify(|r| {
130 r.set_evnten(false);
131 });
132 }
133 }
134}
135
136impl GenericTimer for El1VirtualTimer {
137 fn frequency_hz(&self) -> u32 {
138 self.0.frequency_hz()
139 }
140
141 fn counter(&self) -> u64 {
142 self.0.counter()
143 }
144
145 fn counter_compare(&self) -> u64 {
146 self.0.counter_compare()
147 }
148
149 fn counter_compare_set(&mut self, value: u64) {
150 self.0.counter_compare_set(value)
151 }
152
153 fn countdown(&self) -> u32 {
154 self.0.countdown()
155 }
156
157 fn countdown_set(&mut self, duration_ticks: u32) {
158 self.0.countdown_set(duration_ticks)
159 }
160
161 fn enabled(&self) -> bool {
162 self.0.enabled()
163 }
164
165 fn enable(&self, enabled: bool) {
166 self.0.enable(enabled)
167 }
168
169 fn interrupt_masked(&self) -> bool {
170 self.0.interrupt_masked()
171 }
172
173 fn interrupt_mask(&mut self, mask: bool) {
174 self.0.interrupt_mask(mask)
175 }
176
177 fn interrupt_status(&self) -> bool {
178 self.0.interrupt_status()
179 }
180}