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<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