aarch32_cpu/generic_timer/
el1.rs1use crate::register;
4
5use super::{El0PhysicalTimer, El0VirtualTimer, GenericTimer};
6
7pub struct El1PhysicalTimer(pub(crate) El0PhysicalTimer);
15
16impl El1PhysicalTimer {
17 pub unsafe fn new() -> El1PhysicalTimer {
25 unsafe { El1PhysicalTimer(El0PhysicalTimer::new()) }
26 }
27
28 pub fn el0_access_physical_counter(&mut self, access: bool) {
30 register::Cntkctl::modify(|r| {
31 r.set_el0pcten(access);
32 });
33 }
34
35 pub fn el0_access_physical_timer(&mut self, access: bool) {
37 register::Cntkctl::modify(|r| {
38 r.set_el0pten(access);
39 });
40 }
41}
42
43impl GenericTimer for El1PhysicalTimer {
44 fn frequency_hz(&self) -> u32 {
45 self.0.frequency_hz()
46 }
47
48 fn counter(&self) -> u64 {
49 self.0.counter()
50 }
51
52 fn counter_compare(&self) -> u64 {
53 self.0.counter_compare()
54 }
55
56 fn counter_compare_set(&mut self, value: u64) {
57 self.0.counter_compare_set(value)
58 }
59
60 fn countdown(&self) -> u32 {
61 self.0.countdown()
62 }
63
64 fn countdown_set(&mut self, duration_ticks: u32) {
65 self.0.countdown_set(duration_ticks)
66 }
67
68 fn enabled(&self) -> bool {
69 self.0.enabled()
70 }
71
72 fn enable(&self, enabled: bool) {
73 self.0.enable(enabled)
74 }
75
76 fn interrupt_masked(&self) -> bool {
77 self.0.interrupt_masked()
78 }
79
80 fn interrupt_mask(&mut self, mask: bool) {
81 self.0.interrupt_mask(mask)
82 }
83
84 fn interrupt_status(&self) -> bool {
85 self.0.interrupt_status()
86 }
87}
88
89pub struct El1VirtualTimer(El0VirtualTimer);
97
98impl El1VirtualTimer {
99 pub unsafe fn new() -> El1VirtualTimer {
107 unsafe { El1VirtualTimer(El0VirtualTimer::new()) }
108 }
109
110 pub fn el0_access_virtual_counter(&mut self, access: bool) {
112 register::Cntkctl::modify(|r| {
113 r.set_el0vcten(access);
114 });
115 }
116
117 pub fn el0_access_virtual_timer(&mut self, access: bool) {
119 register::Cntkctl::modify(|r| {
120 r.set_el0vten(access);
121 });
122 }
123
124 pub fn virtual_event_stream_configure(&mut self, event_config: Option<&super::EventConfig>) {
136 if let Some(event_config) = event_config {
137 register::Cntkctl::modify(|r| {
138 r.set_evnti(arbitrary_int::u4::from_u8(event_config.rate as u8));
139 r.set_evntdir(event_config.evntdir == super::EventDir::HighLow);
140 r.set_evnten(true);
141 });
142 } else {
143 register::Cntkctl::modify(|r| {
144 r.set_evnten(false);
145 });
146 }
147 }
148}
149
150impl GenericTimer for El1VirtualTimer {
151 fn frequency_hz(&self) -> u32 {
152 self.0.frequency_hz()
153 }
154
155 fn counter(&self) -> u64 {
156 self.0.counter()
157 }
158
159 fn counter_compare(&self) -> u64 {
160 self.0.counter_compare()
161 }
162
163 fn counter_compare_set(&mut self, value: u64) {
164 self.0.counter_compare_set(value)
165 }
166
167 fn countdown(&self) -> u32 {
168 self.0.countdown()
169 }
170
171 fn countdown_set(&mut self, duration_ticks: u32) {
172 self.0.countdown_set(duration_ticks)
173 }
174
175 fn enabled(&self) -> bool {
176 self.0.enabled()
177 }
178
179 fn enable(&self, enabled: bool) {
180 self.0.enable(enabled)
181 }
182
183 fn interrupt_masked(&self) -> bool {
184 self.0.interrupt_masked()
185 }
186
187 fn interrupt_mask(&mut self, mask: bool) {
188 self.0.interrupt_mask(mask)
189 }
190
191 fn interrupt_status(&self) -> bool {
192 self.0.interrupt_status()
193 }
194}