xref: /cloud-hypervisor/devices/src/legacy/rtc_pl031.rs (revision 9af2968a7dc47b89bf07ea9dc5e735084efcfa3a)
1 // Copyright 2020 Arm Limited (or its affiliates). All rights reserved.
2 // Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 //! ARM PL031 Real Time Clock
6 //!
7 //! This module implements a PL031 Real Time Clock (RTC) that provides to provides long time base counter.
8 //! This is achieved by generating an interrupt signal after counting for a programmed number of cycles of
9 //! a real-time clock input.
10 //!
11 use crate::{read_le_u32, write_le_u32};
12 use std::fmt;
13 use std::sync::{Arc, Barrier};
14 use std::time::Instant;
15 use std::{io, result};
16 use vm_device::interrupt::InterruptSourceGroup;
17 use vm_device::BusDevice;
18 
19 // As you can see in https://static.docs.arm.com/ddi0224/c/real_time_clock_pl031_r1p3_technical_reference_manual_DDI0224C.pdf
20 // at section 3.2 Summary of RTC registers, the total size occupied by this device is 0x000 -> 0xFFC + 4 = 0x1000.
21 // From 0x0 to 0x1C we have following registers:
22 const RTCDR: u64 = 0x0; // Data Register.
23 const RTCMR: u64 = 0x4; // Match Register.
24 const RTCLR: u64 = 0x8; // Load Register.
25 const RTCCR: u64 = 0xc; // Control Register.
26 const RTCIMSC: u64 = 0x10; // Interrupt Mask Set or Clear Register.
27 const RTCRIS: u64 = 0x14; // Raw Interrupt Status.
28 const RTCMIS: u64 = 0x18; // Masked Interrupt Status.
29 const RTCICR: u64 = 0x1c; // Interrupt Clear Register.
30                           // From 0x020 to 0xFDC => reserved space.
31                           // From 0xFE0 to 0x1000 => Peripheral and PrimeCell Identification Registers which are Read Only registers.
32                           // AMBA standard devices have CIDs (Cell IDs) and PIDs (Peripheral IDs). The linux kernel will look for these in order to assert the identity
33                           // of these devices (i.e look at the `amba_device_try_add` function).
34                           // We are putting the expected values (look at 'Reset value' column from above mentioned document) in an array.
35 const PL031_ID: [u8; 8] = [0x31, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1];
36 // We are only interested in the margins.
37 const AMBA_ID_LOW: u64 = 0xFE0;
38 const AMBA_ID_HIGH: u64 = 0x1000;
39 /// Constant to convert seconds to nanoseconds.
40 pub const NANOS_PER_SECOND: u64 = 1_000_000_000;
41 
42 #[derive(Debug)]
43 pub enum Error {
44     BadWriteOffset(u64),
45     InterruptFailure(io::Error),
46 }
47 
48 impl fmt::Display for Error {
49     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50         match self {
51             Error::BadWriteOffset(offset) => write!(f, "Bad Write Offset: {}", offset),
52             Error::InterruptFailure(e) => write!(f, "Failed to trigger interrupt: {}", e),
53         }
54     }
55 }
56 
57 type Result<T> = result::Result<T, Error>;
58 
59 /// Wrapper over `libc::clockid_t` to specify Linux Kernel clock source.
60 pub enum ClockType {
61     /// Equivalent to `libc::CLOCK_MONOTONIC`.
62     Monotonic,
63     /// Equivalent to `libc::CLOCK_REALTIME`.
64     #[allow(dead_code)]
65     Real,
66     /// Equivalent to `libc::CLOCK_PROCESS_CPUTIME_ID`.
67     ProcessCpu,
68     /// Equivalent to `libc::CLOCK_THREAD_CPUTIME_ID`.
69     #[allow(dead_code)]
70     ThreadCpu,
71 }
72 
73 impl From<ClockType> for libc::clockid_t {
74     fn from(ct: ClockType) -> libc::clockid_t {
75         match ct {
76             ClockType::Monotonic => libc::CLOCK_MONOTONIC,
77             ClockType::Real => libc::CLOCK_REALTIME,
78             ClockType::ProcessCpu => libc::CLOCK_PROCESS_CPUTIME_ID,
79             ClockType::ThreadCpu => libc::CLOCK_THREAD_CPUTIME_ID,
80         }
81     }
82 }
83 
84 /// Structure representing the date in local time with nanosecond precision.
85 pub struct LocalTime {
86     /// Seconds in current minute.
87     sec: i32,
88     /// Minutes in current hour.
89     min: i32,
90     /// Hours in current day, 24H format.
91     hour: i32,
92     /// Days in current month.
93     mday: i32,
94     /// Months in current year.
95     mon: i32,
96     /// Years passed since 1900 BC.
97     year: i32,
98     /// Nanoseconds in current second.
99     nsec: i64,
100 }
101 
102 impl LocalTime {
103     /// Returns the [LocalTime](struct.LocalTime.html) structure for the calling moment.
104     #[allow(dead_code)]
105     pub fn now() -> LocalTime {
106         let mut timespec = libc::timespec {
107             tv_sec: 0,
108             tv_nsec: 0,
109         };
110         let mut tm: libc::tm = libc::tm {
111             tm_sec: 0,
112             tm_min: 0,
113             tm_hour: 0,
114             tm_mday: 0,
115             tm_mon: 0,
116             tm_year: 0,
117             tm_wday: 0,
118             tm_yday: 0,
119             tm_isdst: 0,
120             tm_gmtoff: 0,
121             tm_zone: std::ptr::null(),
122         };
123 
124         // Safe because the parameters are valid.
125         unsafe {
126             libc::clock_gettime(libc::CLOCK_REALTIME, &mut timespec);
127             libc::localtime_r(&timespec.tv_sec, &mut tm);
128         }
129 
130         LocalTime {
131             sec: tm.tm_sec,
132             min: tm.tm_min,
133             hour: tm.tm_hour,
134             mday: tm.tm_mday,
135             mon: tm.tm_mon,
136             year: tm.tm_year,
137             nsec: timespec.tv_nsec,
138         }
139     }
140 }
141 
142 impl fmt::Display for LocalTime {
143     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144         write!(
145             f,
146             "{}-{:02}-{:02}T{:02}:{:02}:{:02}.{:09}",
147             self.year + 1900,
148             self.mon + 1,
149             self.mday,
150             self.hour,
151             self.min,
152             self.sec,
153             self.nsec
154         )
155     }
156 }
157 
158 /// Holds a micro-second resolution timestamp with both the real time and cpu time.
159 #[derive(Clone)]
160 pub struct TimestampUs {
161     /// Real time in microseconds.
162     pub time_us: u64,
163     /// Cpu time in microseconds.
164     pub cputime_us: u64,
165 }
166 
167 impl Default for TimestampUs {
168     fn default() -> TimestampUs {
169         TimestampUs {
170             time_us: get_time(ClockType::Monotonic) / 1000,
171             cputime_us: get_time(ClockType::ProcessCpu) / 1000,
172         }
173     }
174 }
175 
176 /// Returns a timestamp in nanoseconds from a monotonic clock.
177 ///
178 /// Uses `_rdstc` on `x86_64` and [`get_time`](fn.get_time.html) on other architectures.
179 #[allow(dead_code)]
180 pub fn timestamp_cycles() -> u64 {
181     #[cfg(target_arch = "x86_64")]
182     // Safe because there's nothing that can go wrong with this call.
183     unsafe {
184         std::arch::x86_64::_rdtsc() as u64
185     }
186     #[cfg(not(target_arch = "x86_64"))]
187     {
188         get_time(ClockType::Monotonic)
189     }
190 }
191 
192 /// Returns a timestamp in nanoseconds based on the provided clock type.
193 ///
194 /// # Arguments
195 ///
196 /// * `clock_type` - Identifier of the Linux Kernel clock on which to act.
197 pub fn get_time(clock_type: ClockType) -> u64 {
198     let mut time_struct = libc::timespec {
199         tv_sec: 0,
200         tv_nsec: 0,
201     };
202     // Safe because the parameters are valid.
203     unsafe { libc::clock_gettime(clock_type.into(), &mut time_struct) };
204     seconds_to_nanoseconds(time_struct.tv_sec).unwrap() as u64 + (time_struct.tv_nsec as u64)
205 }
206 
207 /// Converts a timestamp in seconds to an equivalent one in nanoseconds.
208 /// Returns `None` if the conversion overflows.
209 ///
210 /// # Arguments
211 ///
212 /// * `value` - Timestamp in seconds.
213 pub fn seconds_to_nanoseconds(value: i64) -> Option<i64> {
214     value.checked_mul(NANOS_PER_SECOND as i64)
215 }
216 
217 /// A RTC device following the PL031 specification..
218 pub struct Rtc {
219     previous_now: Instant,
220     tick_offset: i64,
221     // This is used for implementing the RTC alarm. However, in Firecracker we do not need it.
222     match_value: u32,
223     // Writes to this register load an update value into the RTC.
224     load: u32,
225     imsc: u32,
226     ris: u32,
227     interrupt: Arc<Box<dyn InterruptSourceGroup>>,
228 }
229 
230 impl Rtc {
231     /// Constructs an AMBA PL031 RTC device.
232     pub fn new(interrupt: Arc<Box<dyn InterruptSourceGroup>>) -> Self {
233         Self {
234             // This is used only for duration measuring purposes.
235             previous_now: Instant::now(),
236             tick_offset: get_time(ClockType::Real) as i64,
237             match_value: 0,
238             load: 0,
239             imsc: 0,
240             ris: 0,
241             interrupt,
242         }
243     }
244 
245     fn trigger_interrupt(&mut self) -> Result<()> {
246         self.interrupt.trigger(0).map_err(Error::InterruptFailure)?;
247         Ok(())
248     }
249 
250     fn get_time(&self) -> u32 {
251         let ts = (self.tick_offset as i128)
252             + (Instant::now().duration_since(self.previous_now).as_nanos() as i128);
253         (ts / NANOS_PER_SECOND as i128) as u32
254     }
255 
256     fn handle_write(&mut self, offset: u64, val: u32) -> Result<()> {
257         match offset {
258             RTCMR => {
259                 // The MR register is used for implementing the RTC alarm. A real time clock alarm is
260                 // a feature that can be used to allow a computer to 'wake up' after shut down to execute
261                 // tasks every day or on a certain day. It can sometimes be found in the 'Power Management'
262                 // section of a motherboard's BIOS setup. This is functionality that extends beyond
263                 // Firecracker intended use. However, we increment a metric just in case.
264                 self.match_value = val;
265             }
266             RTCLR => {
267                 self.load = val;
268                 self.previous_now = Instant::now();
269                 // If the unwrap fails, then the internal value of the clock has been corrupted and
270                 // we want to terminate the execution of the process.
271                 self.tick_offset = seconds_to_nanoseconds(i64::from(val)).unwrap();
272             }
273             RTCIMSC => {
274                 self.imsc = val & 1;
275                 self.trigger_interrupt()?;
276             }
277             RTCICR => {
278                 // As per above mentioned doc, the interrupt is cleared by writing any data value to
279                 // the Interrupt Clear Register.
280                 self.ris = 0;
281                 self.trigger_interrupt()?;
282             }
283             RTCCR => (), // ignore attempts to turn off the timer.
284             o => {
285                 return Err(Error::BadWriteOffset(o));
286             }
287         }
288         Ok(())
289     }
290 }
291 
292 impl BusDevice for Rtc {
293     fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
294         let v;
295         let mut read_ok = true;
296 
297         if (AMBA_ID_LOW..AMBA_ID_HIGH).contains(&offset) {
298             let index = ((offset - AMBA_ID_LOW) >> 2) as usize;
299             v = u32::from(PL031_ID[index]);
300         } else {
301             v = match offset {
302                 RTCDR => self.get_time(),
303                 RTCMR => {
304                     // Even though we are not implementing RTC alarm we return the last value
305                     self.match_value
306                 }
307                 RTCLR => self.load,
308                 RTCCR => 1, // RTC is always enabled.
309                 RTCIMSC => self.imsc,
310                 RTCRIS => self.ris,
311                 RTCMIS => self.ris & self.imsc,
312                 _ => {
313                     read_ok = false;
314                     0
315                 }
316             };
317         }
318         if read_ok && data.len() <= 4 {
319             write_le_u32(data, v);
320         } else {
321             warn!(
322                 "Invalid RTC PL031 read: offset {}, data length {}",
323                 offset,
324                 data.len()
325             );
326         }
327     }
328 
329     fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
330         if data.len() <= 4 {
331             let v = read_le_u32(data);
332             if let Err(e) = self.handle_write(offset, v) {
333                 warn!("Failed to write to RTC PL031 device: {}", e);
334             }
335         } else {
336             warn!(
337                 "Invalid RTC PL031 write: offset {}, data length {}",
338                 offset,
339                 data.len()
340             );
341         }
342 
343         None
344     }
345 }
346 
347 #[cfg(test)]
348 mod tests {
349     use super::*;
350     use crate::{
351         read_be_u16, read_be_u32, read_le_i32, read_le_u16, read_le_u32, read_le_u64, write_be_u16,
352         write_be_u32, write_le_i32, write_le_u16, write_le_u32, write_le_u64,
353     };
354     use std::sync::Arc;
355     use vm_device::interrupt::{InterruptIndex, InterruptSourceConfig};
356     use vmm_sys_util::eventfd::EventFd;
357 
358     const LEGACY_RTC_MAPPED_IO_START: u64 = 0x0901_0000;
359 
360     #[test]
361     fn test_get_time() {
362         for _ in 0..1000 {
363             assert!(get_time(ClockType::Monotonic) <= get_time(ClockType::Monotonic));
364         }
365 
366         for _ in 0..1000 {
367             assert!(get_time(ClockType::ProcessCpu) <= get_time(ClockType::ProcessCpu));
368         }
369 
370         for _ in 0..1000 {
371             assert!(get_time(ClockType::ThreadCpu) <= get_time(ClockType::ThreadCpu));
372         }
373 
374         assert_ne!(get_time(ClockType::Real), 0);
375     }
376 
377     #[test]
378     fn test_local_time_display() {
379         let local_time = LocalTime {
380             sec: 30,
381             min: 15,
382             hour: 10,
383             mday: 4,
384             mon: 6,
385             year: 119,
386             nsec: 123_456_789,
387         };
388         assert_eq!(
389             String::from("2019-07-04T10:15:30.123456789"),
390             local_time.to_string()
391         );
392 
393         let local_time = LocalTime {
394             sec: 5,
395             min: 5,
396             hour: 5,
397             mday: 23,
398             mon: 7,
399             year: 44,
400             nsec: 123,
401         };
402         assert_eq!(
403             String::from("1944-08-23T05:05:05.000000123"),
404             local_time.to_string()
405         );
406 
407         let local_time = LocalTime::now();
408         assert!(local_time.mon >= 0 && local_time.mon <= 11);
409     }
410 
411     #[test]
412     fn test_seconds_to_nanoseconds() {
413         assert_eq!(
414             seconds_to_nanoseconds(100).unwrap() as u64,
415             100 * NANOS_PER_SECOND
416         );
417 
418         assert!(seconds_to_nanoseconds(9_223_372_037).is_none());
419     }
420 
421     struct TestInterrupt {
422         event_fd: EventFd,
423     }
424 
425     impl InterruptSourceGroup for TestInterrupt {
426         fn trigger(&self, _index: InterruptIndex) -> result::Result<(), std::io::Error> {
427             self.event_fd.write(1)
428         }
429 
430         fn update(
431             &self,
432             _index: InterruptIndex,
433             _config: InterruptSourceConfig,
434         ) -> result::Result<(), std::io::Error> {
435             Ok(())
436         }
437 
438         fn notifier(&self, _index: InterruptIndex) -> Option<EventFd> {
439             Some(self.event_fd.try_clone().unwrap())
440         }
441     }
442 
443     impl TestInterrupt {
444         fn new(event_fd: EventFd) -> Self {
445             TestInterrupt { event_fd }
446         }
447     }
448 
449     #[test]
450     fn test_rtc_read_write_and_event() {
451         let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
452 
453         let mut rtc = Rtc::new(Arc::new(Box::new(TestInterrupt::new(
454             intr_evt.try_clone().unwrap(),
455         ))));
456         let mut data = [0; 4];
457 
458         // Read and write to the MR register.
459         write_le_u32(&mut data, 123);
460         rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCMR, &data);
461         rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCMR, &mut data);
462         let v = read_le_u32(&data);
463         assert_eq!(v, 123);
464 
465         // Read and write to the LR register.
466         let v = get_time(ClockType::Real);
467         write_le_u32(&mut data, (v / NANOS_PER_SECOND) as u32);
468         let previous_now_before = rtc.previous_now;
469         rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCLR, &data);
470 
471         assert!(rtc.previous_now > previous_now_before);
472 
473         rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCLR, &mut data);
474         let v_read = read_le_u32(&data);
475         assert_eq!((v / NANOS_PER_SECOND) as u32, v_read);
476 
477         // Read and write to IMSC register.
478         // Test with non zero value.
479         let non_zero = 1;
480         write_le_u32(&mut data, non_zero);
481         rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCIMSC, &data);
482         // The interrupt line should be on.
483         assert!(rtc.interrupt.notifier(0).unwrap().read().unwrap() == 1);
484         rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCIMSC, &mut data);
485         let v = read_le_u32(&data);
486         assert_eq!(non_zero & 1, v);
487 
488         // Now test with 0.
489         write_le_u32(&mut data, 0);
490         rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCIMSC, &data);
491         rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCIMSC, &mut data);
492         let v = read_le_u32(&data);
493         assert_eq!(0, v);
494 
495         // Read and write to the ICR register.
496         write_le_u32(&mut data, 1);
497         rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCICR, &data);
498         // The interrupt line should be on.
499         assert!(rtc.interrupt.notifier(0).unwrap().read().unwrap() > 1);
500         let v_before = read_le_u32(&data);
501 
502         rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCICR, &mut data);
503         let v = read_le_u32(&data);
504         // ICR is a  write only register. Data received should stay equal to data sent.
505         assert_eq!(v, v_before);
506 
507         // Attempts to turn off the RTC should not go through.
508         write_le_u32(&mut data, 0);
509         rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCCR, &data);
510         rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCCR, &mut data);
511         let v = read_le_u32(&data);
512         assert_eq!(v, 1);
513 
514         // Attempts to write beyond the writable space. Using here the space used to read
515         // the CID and PID from.
516         write_le_u32(&mut data, 0);
517         rtc.write(LEGACY_RTC_MAPPED_IO_START, AMBA_ID_LOW, &data);
518         // However, reading from the AMBA_ID_LOW should succeed upon read.
519 
520         let mut data = [0; 4];
521         rtc.read(LEGACY_RTC_MAPPED_IO_START, AMBA_ID_LOW, &mut data);
522         let index = AMBA_ID_LOW + 3;
523         assert_eq!(data[0], PL031_ID[((index - AMBA_ID_LOW) >> 2) as usize]);
524     }
525 
526     macro_rules! byte_order_test_read_write {
527         ($test_name: ident, $write_fn_name: ident, $read_fn_name: ident, $is_be: expr, $data_type: ty) => {
528             #[test]
529             fn $test_name() {
530                 #[allow(overflowing_literals)]
531                 let test_cases = [
532                     (
533                         0x0123_4567_89AB_CDEF as u64,
534                         [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef],
535                     ),
536                     (
537                         0x0000_0000_0000_0000 as u64,
538                         [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
539                     ),
540                     (
541                         0x1923_2345_ABF3_CCD4 as u64,
542                         [0x19, 0x23, 0x23, 0x45, 0xAB, 0xF3, 0xCC, 0xD4],
543                     ),
544                     (
545                         0x0FF0_0FF0_0FF0_0FF0 as u64,
546                         [0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0],
547                     ),
548                     (
549                         0xFFFF_FFFF_FFFF_FFFF as u64,
550                         [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
551                     ),
552                     (
553                         0x89AB_12D4_C2D2_09BB as u64,
554                         [0x89, 0xAB, 0x12, 0xD4, 0xC2, 0xD2, 0x09, 0xBB],
555                     ),
556                 ];
557 
558                 let type_size = std::mem::size_of::<$data_type>();
559                 for (test_val, v_arr) in &test_cases {
560                     let v = *test_val as $data_type;
561                     let cmp_iter: Box<dyn Iterator<Item = _>> = if $is_be {
562                         Box::new(v_arr[(8 - type_size)..].iter())
563                     } else {
564                         Box::new(v_arr.iter().rev())
565                     };
566                     // test write
567                     let mut write_arr = vec![Default::default(); type_size];
568                     $write_fn_name(&mut write_arr, v);
569                     for (cmp, cur) in cmp_iter.zip(write_arr.iter()) {
570                         assert_eq!(*cmp, *cur as u8)
571                     }
572                     // test read
573                     let read_val = $read_fn_name(&write_arr);
574                     assert_eq!(v, read_val);
575                 }
576             }
577         };
578     }
579 
580     byte_order_test_read_write!(test_le_u16, write_le_u16, read_le_u16, false, u16);
581     byte_order_test_read_write!(test_le_u32, write_le_u32, read_le_u32, false, u32);
582     byte_order_test_read_write!(test_le_u64, write_le_u64, read_le_u64, false, u64);
583     byte_order_test_read_write!(test_le_i32, write_le_i32, read_le_i32, false, i32);
584     byte_order_test_read_write!(test_be_u16, write_be_u16, read_be_u16, true, u16);
585     byte_order_test_read_write!(test_be_u32, write_be_u32, read_be_u32, true, u32);
586 }
587