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