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(×pec.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<dyn InterruptSourceGroup>, 228 } 229 230 impl Rtc { 231 /// Constructs an AMBA PL031 RTC device. 232 pub fn new(interrupt: Arc<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 mut read_ok = true; 295 296 let v = if (AMBA_ID_LOW..AMBA_ID_HIGH).contains(&offset) { 297 let index = ((offset - AMBA_ID_LOW) >> 2) as usize; 298 u32::from(PL031_ID[index]) 299 } else { 300 match offset { 301 RTCDR => self.get_time(), 302 RTCMR => { 303 // Even though we are not implementing RTC alarm we return the last value 304 self.match_value 305 } 306 RTCLR => self.load, 307 RTCCR => 1, // RTC is always enabled. 308 RTCIMSC => self.imsc, 309 RTCRIS => self.ris, 310 RTCMIS => self.ris & self.imsc, 311 _ => { 312 read_ok = false; 313 0 314 } 315 } 316 }; 317 if read_ok && data.len() <= 4 { 318 write_le_u32(data, v); 319 } else { 320 warn!( 321 "Invalid RTC PL031 read: offset {}, data length {}", 322 offset, 323 data.len() 324 ); 325 } 326 } 327 328 fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> { 329 if data.len() <= 4 { 330 let v = read_le_u32(data); 331 if let Err(e) = self.handle_write(offset, v) { 332 warn!("Failed to write to RTC PL031 device: {}", e); 333 } 334 } else { 335 warn!( 336 "Invalid RTC PL031 write: offset {}, data length {}", 337 offset, 338 data.len() 339 ); 340 } 341 342 None 343 } 344 } 345 346 #[cfg(test)] 347 mod tests { 348 use super::*; 349 use crate::{ 350 read_be_u16, read_be_u32, read_le_i32, read_le_u16, read_le_u32, read_le_u64, write_be_u16, 351 write_be_u32, write_le_i32, write_le_u16, write_le_u32, write_le_u64, 352 }; 353 use std::sync::Arc; 354 use vm_device::interrupt::{InterruptIndex, InterruptSourceConfig}; 355 use vmm_sys_util::eventfd::EventFd; 356 357 const LEGACY_RTC_MAPPED_IO_START: u64 = 0x0901_0000; 358 359 #[test] 360 fn test_get_time() { 361 for _ in 0..1000 { 362 assert!(get_time(ClockType::Monotonic) <= get_time(ClockType::Monotonic)); 363 } 364 365 for _ in 0..1000 { 366 assert!(get_time(ClockType::ProcessCpu) <= get_time(ClockType::ProcessCpu)); 367 } 368 369 for _ in 0..1000 { 370 assert!(get_time(ClockType::ThreadCpu) <= get_time(ClockType::ThreadCpu)); 371 } 372 373 assert_ne!(get_time(ClockType::Real), 0); 374 } 375 376 #[test] 377 fn test_local_time_display() { 378 let local_time = LocalTime { 379 sec: 30, 380 min: 15, 381 hour: 10, 382 mday: 4, 383 mon: 6, 384 year: 119, 385 nsec: 123_456_789, 386 }; 387 assert_eq!( 388 String::from("2019-07-04T10:15:30.123456789"), 389 local_time.to_string() 390 ); 391 392 let local_time = LocalTime { 393 sec: 5, 394 min: 5, 395 hour: 5, 396 mday: 23, 397 mon: 7, 398 year: 44, 399 nsec: 123, 400 }; 401 assert_eq!( 402 String::from("1944-08-23T05:05:05.000000123"), 403 local_time.to_string() 404 ); 405 406 let local_time = LocalTime::now(); 407 assert!(local_time.mon >= 0 && local_time.mon <= 11); 408 } 409 410 #[test] 411 fn test_seconds_to_nanoseconds() { 412 assert_eq!( 413 seconds_to_nanoseconds(100).unwrap() as u64, 414 100 * NANOS_PER_SECOND 415 ); 416 417 assert!(seconds_to_nanoseconds(9_223_372_037).is_none()); 418 } 419 420 struct TestInterrupt { 421 event_fd: EventFd, 422 } 423 424 impl InterruptSourceGroup for TestInterrupt { 425 fn trigger(&self, _index: InterruptIndex) -> result::Result<(), std::io::Error> { 426 self.event_fd.write(1) 427 } 428 429 fn update( 430 &self, 431 _index: InterruptIndex, 432 _config: InterruptSourceConfig, 433 ) -> result::Result<(), std::io::Error> { 434 Ok(()) 435 } 436 437 fn notifier(&self, _index: InterruptIndex) -> Option<EventFd> { 438 Some(self.event_fd.try_clone().unwrap()) 439 } 440 } 441 442 impl TestInterrupt { 443 fn new(event_fd: EventFd) -> Self { 444 TestInterrupt { event_fd } 445 } 446 } 447 448 #[test] 449 fn test_rtc_read_write_and_event() { 450 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap(); 451 452 let mut rtc = Rtc::new(Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))); 453 let mut data = [0; 4]; 454 455 // Read and write to the MR register. 456 write_le_u32(&mut data, 123); 457 rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCMR, &data); 458 rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCMR, &mut data); 459 let v = read_le_u32(&data); 460 assert_eq!(v, 123); 461 462 // Read and write to the LR register. 463 let v = get_time(ClockType::Real); 464 write_le_u32(&mut data, (v / NANOS_PER_SECOND) as u32); 465 let previous_now_before = rtc.previous_now; 466 rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCLR, &data); 467 468 assert!(rtc.previous_now > previous_now_before); 469 470 rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCLR, &mut data); 471 let v_read = read_le_u32(&data); 472 assert_eq!((v / NANOS_PER_SECOND) as u32, v_read); 473 474 // Read and write to IMSC register. 475 // Test with non zero value. 476 let non_zero = 1; 477 write_le_u32(&mut data, non_zero); 478 rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCIMSC, &data); 479 // The interrupt line should be on. 480 assert!(rtc.interrupt.notifier(0).unwrap().read().unwrap() == 1); 481 rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCIMSC, &mut data); 482 let v = read_le_u32(&data); 483 assert_eq!(non_zero & 1, v); 484 485 // Now test with 0. 486 write_le_u32(&mut data, 0); 487 rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCIMSC, &data); 488 rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCIMSC, &mut data); 489 let v = read_le_u32(&data); 490 assert_eq!(0, v); 491 492 // Read and write to the ICR register. 493 write_le_u32(&mut data, 1); 494 rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCICR, &data); 495 // The interrupt line should be on. 496 assert!(rtc.interrupt.notifier(0).unwrap().read().unwrap() > 1); 497 let v_before = read_le_u32(&data); 498 499 rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCICR, &mut data); 500 let v = read_le_u32(&data); 501 // ICR is a write only register. Data received should stay equal to data sent. 502 assert_eq!(v, v_before); 503 504 // Attempts to turn off the RTC should not go through. 505 write_le_u32(&mut data, 0); 506 rtc.write(LEGACY_RTC_MAPPED_IO_START, RTCCR, &data); 507 rtc.read(LEGACY_RTC_MAPPED_IO_START, RTCCR, &mut data); 508 let v = read_le_u32(&data); 509 assert_eq!(v, 1); 510 511 // Attempts to write beyond the writable space. Using here the space used to read 512 // the CID and PID from. 513 write_le_u32(&mut data, 0); 514 rtc.write(LEGACY_RTC_MAPPED_IO_START, AMBA_ID_LOW, &data); 515 // However, reading from the AMBA_ID_LOW should succeed upon read. 516 517 let mut data = [0; 4]; 518 rtc.read(LEGACY_RTC_MAPPED_IO_START, AMBA_ID_LOW, &mut data); 519 let index = AMBA_ID_LOW + 3; 520 assert_eq!(data[0], PL031_ID[((index - AMBA_ID_LOW) >> 2) as usize]); 521 } 522 523 macro_rules! byte_order_test_read_write { 524 ($test_name: ident, $write_fn_name: ident, $read_fn_name: ident, $is_be: expr, $data_type: ty) => { 525 #[test] 526 fn $test_name() { 527 #[allow(overflowing_literals)] 528 let test_cases = [ 529 ( 530 0x0123_4567_89AB_CDEF as u64, 531 [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], 532 ), 533 ( 534 0x0000_0000_0000_0000 as u64, 535 [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], 536 ), 537 ( 538 0x1923_2345_ABF3_CCD4 as u64, 539 [0x19, 0x23, 0x23, 0x45, 0xAB, 0xF3, 0xCC, 0xD4], 540 ), 541 ( 542 0x0FF0_0FF0_0FF0_0FF0 as u64, 543 [0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0], 544 ), 545 ( 546 0xFFFF_FFFF_FFFF_FFFF as u64, 547 [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], 548 ), 549 ( 550 0x89AB_12D4_C2D2_09BB as u64, 551 [0x89, 0xAB, 0x12, 0xD4, 0xC2, 0xD2, 0x09, 0xBB], 552 ), 553 ]; 554 555 let type_size = std::mem::size_of::<$data_type>(); 556 for (test_val, v_arr) in &test_cases { 557 let v = *test_val as $data_type; 558 let cmp_iter: Box<dyn Iterator<Item = _>> = if $is_be { 559 Box::new(v_arr[(8 - type_size)..].iter()) 560 } else { 561 Box::new(v_arr.iter().rev()) 562 }; 563 // test write 564 let mut write_arr = vec![Default::default(); type_size]; 565 $write_fn_name(&mut write_arr, v); 566 for (cmp, cur) in cmp_iter.zip(write_arr.iter()) { 567 assert_eq!(*cmp, *cur as u8) 568 } 569 // test read 570 let read_val = $read_fn_name(&write_arr); 571 assert_eq!(v, read_val); 572 } 573 } 574 }; 575 } 576 577 byte_order_test_read_write!(test_le_u16, write_le_u16, read_le_u16, false, u16); 578 byte_order_test_read_write!(test_le_u32, write_le_u32, read_le_u32, false, u32); 579 byte_order_test_read_write!(test_le_u64, write_le_u64, read_le_u64, false, u64); 580 byte_order_test_read_write!(test_le_i32, write_le_i32, read_le_i32, false, i32); 581 byte_order_test_read_write!(test_be_u16, write_be_u16, read_be_u16, true, u16); 582 byte_order_test_read_write!(test_be_u32, write_be_u32, read_be_u32, true, u32); 583 } 584