1 // Copyright 2021 Arm Limited (or its affiliates). All rights reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 4 //! ARM PrimeCell UART(PL011) 5 //! 6 //! This module implements an ARM PrimeCell UART(PL011). 7 //! 8 9 use crate::{read_le_u32, write_le_u32}; 10 use std::collections::VecDeque; 11 use std::fmt; 12 use std::sync::{Arc, Barrier}; 13 use std::time::Instant; 14 use std::{io, result}; 15 use versionize::{VersionMap, Versionize, VersionizeResult}; 16 use versionize_derive::Versionize; 17 use vm_device::interrupt::InterruptSourceGroup; 18 use vm_device::BusDevice; 19 use vm_migration::{ 20 Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable, VersionMapped, 21 }; 22 23 /* Registers */ 24 const UARTDR: u64 = 0; 25 const UARTRSR_UARTECR: u64 = 1; 26 const UARTFR: u64 = 6; 27 const UARTILPR: u64 = 8; 28 const UARTIBRD: u64 = 9; 29 const UARTFBRD: u64 = 10; 30 const UARTLCR_H: u64 = 11; 31 const UARTCR: u64 = 12; 32 const UARTIFLS: u64 = 13; 33 const UARTIMSC: u64 = 14; 34 const UARTRIS: u64 = 15; 35 const UARTMIS: u64 = 16; 36 const UARTICR: u64 = 17; 37 const UARTDMACR: u64 = 18; 38 const UARTDEBUG: u64 = 0x3c0; 39 40 const PL011_INT_TX: u32 = 0x20; 41 const PL011_INT_RX: u32 = 0x10; 42 43 const PL011_FLAG_RXFF: u32 = 0x40; 44 const PL011_FLAG_RXFE: u32 = 0x10; 45 46 const PL011_ID: [u8; 8] = [0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1]; 47 // We are only interested in the margins. 48 const AMBA_ID_LOW: u64 = 0x3f8; 49 const AMBA_ID_HIGH: u64 = 0x401; 50 51 #[derive(Debug)] 52 pub enum Error { 53 BadWriteOffset(u64), 54 DmaNotImplemented, 55 InterruptFailure(io::Error), 56 WriteAllFailure(io::Error), 57 FlushFailure(io::Error), 58 } 59 60 impl fmt::Display for Error { 61 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 62 match self { 63 Error::BadWriteOffset(offset) => write!(f, "pl011_write: Bad Write Offset: {}", offset), 64 Error::DmaNotImplemented => write!(f, "pl011: DMA not implemented."), 65 Error::InterruptFailure(e) => write!(f, "Failed to trigger interrupt: {}", e), 66 Error::WriteAllFailure(e) => write!(f, "Failed to write: {}", e), 67 Error::FlushFailure(e) => write!(f, "Failed to flush: {}", e), 68 } 69 } 70 } 71 72 type Result<T> = result::Result<T, Error>; 73 74 /// A PL011 device following the PL011 specification. 75 pub struct Pl011 { 76 id: String, 77 flags: u32, 78 lcr: u32, 79 rsr: u32, 80 cr: u32, 81 dmacr: u32, 82 debug: u32, 83 int_enabled: u32, 84 int_level: u32, 85 read_fifo: VecDeque<u8>, 86 ilpr: u32, 87 ibrd: u32, 88 fbrd: u32, 89 ifl: u32, 90 read_count: u32, 91 read_trigger: u32, 92 irq: Arc<dyn InterruptSourceGroup>, 93 out: Option<Box<dyn io::Write + Send>>, 94 timestamp: std::time::Instant, 95 } 96 97 #[derive(Versionize)] 98 pub struct Pl011State { 99 flags: u32, 100 lcr: u32, 101 rsr: u32, 102 cr: u32, 103 dmacr: u32, 104 debug: u32, 105 int_enabled: u32, 106 int_level: u32, 107 read_fifo: Vec<u8>, 108 ilpr: u32, 109 ibrd: u32, 110 fbrd: u32, 111 ifl: u32, 112 read_count: u32, 113 read_trigger: u32, 114 } 115 116 impl VersionMapped for Pl011State {} 117 118 impl Pl011 { 119 /// Constructs an AMBA PL011 UART device. 120 pub fn new( 121 id: String, 122 irq: Arc<dyn InterruptSourceGroup>, 123 out: Option<Box<dyn io::Write + Send>>, 124 timestamp: Instant, 125 ) -> Self { 126 Self { 127 id, 128 flags: 0x90u32, 129 lcr: 0u32, 130 rsr: 0u32, 131 cr: 0x300u32, 132 dmacr: 0u32, 133 debug: 0u32, 134 int_enabled: 0u32, 135 int_level: 0u32, 136 read_fifo: VecDeque::new(), 137 ilpr: 0u32, 138 ibrd: 0u32, 139 fbrd: 0u32, 140 ifl: 0x12u32, 141 read_count: 0u32, 142 read_trigger: 1u32, 143 irq, 144 out, 145 timestamp, 146 } 147 } 148 149 pub fn set_out(&mut self, out: Box<dyn io::Write + Send>) { 150 self.out = Some(out); 151 } 152 153 fn state(&self) -> Pl011State { 154 Pl011State { 155 flags: self.flags, 156 lcr: self.lcr, 157 rsr: self.rsr, 158 cr: self.cr, 159 dmacr: self.dmacr, 160 debug: self.debug, 161 int_enabled: self.int_enabled, 162 int_level: self.int_level, 163 read_fifo: self.read_fifo.clone().into(), 164 ilpr: self.ilpr, 165 ibrd: self.ibrd, 166 fbrd: self.fbrd, 167 ifl: self.ifl, 168 read_count: self.read_count, 169 read_trigger: self.read_trigger, 170 } 171 } 172 173 fn set_state(&mut self, state: &Pl011State) { 174 self.flags = state.flags; 175 self.lcr = state.lcr; 176 self.rsr = state.rsr; 177 self.cr = state.cr; 178 self.dmacr = state.dmacr; 179 self.debug = state.debug; 180 self.int_enabled = state.int_enabled; 181 self.int_level = state.int_level; 182 self.read_fifo = state.read_fifo.clone().into(); 183 self.ilpr = state.ilpr; 184 self.ibrd = state.ibrd; 185 self.fbrd = state.fbrd; 186 self.ifl = state.ifl; 187 self.read_count = state.read_count; 188 self.read_trigger = state.read_trigger; 189 } 190 191 /// Queues raw bytes for the guest to read and signals the interrupt 192 pub fn queue_input_bytes(&mut self, c: &[u8]) -> vmm_sys_util::errno::Result<()> { 193 self.read_fifo.extend(c); 194 self.read_count += c.len() as u32; 195 self.flags &= !PL011_FLAG_RXFE; 196 197 if ((self.lcr & 0x10) == 0) || (self.read_count == 16) { 198 self.flags |= PL011_FLAG_RXFF; 199 } 200 201 if self.read_count >= self.read_trigger { 202 self.int_level |= PL011_INT_RX; 203 self.trigger_interrupt()?; 204 } 205 206 Ok(()) 207 } 208 209 pub fn flush_output(&mut self) -> result::Result<(), io::Error> { 210 if let Some(out) = self.out.as_mut() { 211 out.flush()?; 212 } 213 Ok(()) 214 } 215 216 fn pl011_get_baudrate(&self) -> u32 { 217 if self.fbrd == 0 { 218 return 0; 219 } 220 221 let clk = 24_000_000; // We set the APB_PLCK to 24M in device tree 222 (clk / ((self.ibrd << 6) + self.fbrd)) << 2 223 } 224 225 fn pl011_trace_baudrate_change(&self) { 226 debug!( 227 "=== New baudrate: {:#?} (clk: {:#?}Hz, ibrd: {:#?}, fbrd: {:#?}) ===", 228 self.pl011_get_baudrate(), 229 24_000_000, // We set the APB_PLCK to 24M in device tree 230 self.ibrd, 231 self.fbrd 232 ); 233 } 234 235 fn pl011_set_read_trigger(&mut self) { 236 self.read_trigger = 1; 237 } 238 239 fn handle_write(&mut self, offset: u64, val: u32) -> Result<()> { 240 match offset >> 2 { 241 UARTDR => { 242 self.int_level |= PL011_INT_TX; 243 if let Some(out) = self.out.as_mut() { 244 out.write_all(&[val.to_le_bytes()[0]]) 245 .map_err(Error::WriteAllFailure)?; 246 out.flush().map_err(Error::FlushFailure)?; 247 } 248 } 249 UARTRSR_UARTECR => { 250 self.rsr = 0; 251 } 252 UARTFR => { /* Writes to Flag register are ignored.*/ } 253 UARTILPR => { 254 self.ilpr = val; 255 } 256 UARTIBRD => { 257 self.ibrd = val; 258 self.pl011_trace_baudrate_change(); 259 } 260 UARTFBRD => { 261 self.fbrd = val; 262 self.pl011_trace_baudrate_change(); 263 } 264 UARTLCR_H => { 265 /* Reset the FIFO state on FIFO enable or disable */ 266 if ((self.lcr ^ val) & 0x10) != 0 { 267 self.read_count = 0; 268 } 269 self.lcr = val; 270 self.pl011_set_read_trigger(); 271 } 272 UARTCR => { 273 self.cr = val; 274 } 275 UARTIFLS => { 276 self.ifl = val; 277 self.pl011_set_read_trigger(); 278 } 279 UARTIMSC => { 280 self.int_enabled = val; 281 self.trigger_interrupt().map_err(Error::InterruptFailure)?; 282 } 283 UARTICR => { 284 self.int_level &= !val; 285 self.trigger_interrupt().map_err(Error::InterruptFailure)?; 286 } 287 UARTDMACR => { 288 self.dmacr = val; 289 if (val & 3) != 0 { 290 return Err(Error::DmaNotImplemented); 291 } 292 } 293 UARTDEBUG => { 294 self.debug = val; 295 self.handle_debug(); 296 } 297 off => { 298 debug!("PL011: Bad write offset, offset: {}", off); 299 return Err(Error::BadWriteOffset(off)); 300 } 301 } 302 Ok(()) 303 } 304 305 fn handle_debug(&self) { 306 let elapsed = self.timestamp.elapsed(); 307 308 match self.debug { 309 0x00..=0x1f => warn!( 310 "[Debug I/O port: Firmware code: 0x{:x}] {}.{:>06} seconds", 311 self.debug, 312 elapsed.as_secs(), 313 elapsed.as_micros() 314 ), 315 0x20..=0x3f => warn!( 316 "[Debug I/O port: Bootloader code: 0x{:x}] {}.{:>06} seconds", 317 self.debug, 318 elapsed.as_secs(), 319 elapsed.as_micros() 320 ), 321 0x40..=0x5f => warn!( 322 "[Debug I/O port: Kernel code: 0x{:x}] {}.{:>06} seconds", 323 self.debug, 324 elapsed.as_secs(), 325 elapsed.as_micros() 326 ), 327 0x60..=0x7f => warn!( 328 "[Debug I/O port: Userspace code: 0x{:x}] {}.{:>06} seconds", 329 self.debug, 330 elapsed.as_secs(), 331 elapsed.as_micros() 332 ), 333 _ => {} 334 } 335 } 336 337 fn trigger_interrupt(&mut self) -> result::Result<(), io::Error> { 338 self.irq.trigger(0) 339 } 340 } 341 342 impl BusDevice for Pl011 { 343 fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) { 344 let mut read_ok = true; 345 let v = if (AMBA_ID_LOW..AMBA_ID_HIGH).contains(&(offset >> 2)) { 346 let index = ((offset - 0xfe0) >> 2) as usize; 347 u32::from(PL011_ID[index]) 348 } else { 349 match offset >> 2 { 350 UARTDR => { 351 self.flags &= !PL011_FLAG_RXFF; 352 let c: u32 = self.read_fifo.pop_front().unwrap_or_default().into(); 353 if self.read_count > 0 { 354 self.read_count -= 1; 355 } 356 if self.read_count == 0 { 357 self.flags |= PL011_FLAG_RXFE; 358 } 359 if self.read_count == (self.read_trigger - 1) { 360 self.int_level &= !PL011_INT_RX; 361 } 362 self.rsr = c >> 8; 363 c 364 } 365 UARTRSR_UARTECR => self.rsr, 366 UARTFR => self.flags, 367 UARTILPR => self.ilpr, 368 UARTIBRD => self.ibrd, 369 UARTFBRD => self.fbrd, 370 UARTLCR_H => self.lcr, 371 UARTCR => self.cr, 372 UARTIFLS => self.ifl, 373 UARTIMSC => self.int_enabled, 374 UARTRIS => self.int_level, 375 UARTMIS => self.int_level & self.int_enabled, 376 UARTDMACR => self.dmacr, 377 UARTDEBUG => self.debug, 378 _ => { 379 read_ok = false; 380 0 381 } 382 } 383 }; 384 385 if read_ok && data.len() <= 4 { 386 write_le_u32(data, v); 387 } else { 388 warn!( 389 "Invalid PL011 read: offset {}, data length {}", 390 offset, 391 data.len() 392 ); 393 } 394 } 395 396 fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> { 397 if data.len() <= 4 { 398 let v = read_le_u32(data); 399 if let Err(e) = self.handle_write(offset, v) { 400 warn!("Failed to write to PL011 device: {}", e); 401 } 402 } else { 403 warn!( 404 "Invalid PL011 write: offset {}, data length {}", 405 offset, 406 data.len() 407 ); 408 } 409 410 None 411 } 412 } 413 414 impl Snapshottable for Pl011 { 415 fn id(&self) -> String { 416 self.id.clone() 417 } 418 419 fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> { 420 Snapshot::new_from_versioned_state(&self.id, &self.state()) 421 } 422 423 fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { 424 self.set_state(&snapshot.to_versioned_state(&self.id)?); 425 Ok(()) 426 } 427 } 428 429 impl Pausable for Pl011 {} 430 impl Transportable for Pl011 {} 431 impl Migratable for Pl011 {} 432 433 #[cfg(test)] 434 mod tests { 435 use super::*; 436 use std::io; 437 use std::sync::{Arc, Mutex}; 438 use vm_device::interrupt::{InterruptIndex, InterruptSourceConfig}; 439 use vmm_sys_util::eventfd::EventFd; 440 441 const SERIAL_NAME: &str = "serial"; 442 443 struct TestInterrupt { 444 event_fd: EventFd, 445 } 446 447 impl InterruptSourceGroup for TestInterrupt { 448 fn trigger(&self, _index: InterruptIndex) -> result::Result<(), std::io::Error> { 449 self.event_fd.write(1) 450 } 451 fn update( 452 &self, 453 _index: InterruptIndex, 454 _config: InterruptSourceConfig, 455 _masked: bool, 456 ) -> result::Result<(), std::io::Error> { 457 Ok(()) 458 } 459 fn notifier(&self, _index: InterruptIndex) -> Option<EventFd> { 460 Some(self.event_fd.try_clone().unwrap()) 461 } 462 } 463 464 impl TestInterrupt { 465 fn new(event_fd: EventFd) -> Self { 466 TestInterrupt { event_fd } 467 } 468 } 469 470 #[derive(Clone)] 471 struct SharedBuffer { 472 buf: Arc<Mutex<Vec<u8>>>, 473 } 474 475 impl SharedBuffer { 476 fn new() -> SharedBuffer { 477 SharedBuffer { 478 buf: Arc::new(Mutex::new(Vec::new())), 479 } 480 } 481 } 482 483 impl io::Write for SharedBuffer { 484 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 485 self.buf.lock().unwrap().write(buf) 486 } 487 fn flush(&mut self) -> io::Result<()> { 488 self.buf.lock().unwrap().flush() 489 } 490 } 491 492 #[test] 493 fn pl011_output() { 494 let intr_evt = EventFd::new(0).unwrap(); 495 let pl011_out = SharedBuffer::new(); 496 let mut pl011 = Pl011::new( 497 String::from(SERIAL_NAME), 498 Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())), 499 Some(Box::new(pl011_out.clone())), 500 Instant::now(), 501 ); 502 503 pl011.write(0, UARTDR as u64, &[b'x', b'y']); 504 pl011.write(0, UARTDR as u64, &[b'a']); 505 pl011.write(0, UARTDR as u64, &[b'b']); 506 pl011.write(0, UARTDR as u64, &[b'c']); 507 assert_eq!( 508 pl011_out.buf.lock().unwrap().as_slice(), 509 &[b'x', b'a', b'b', b'c'] 510 ); 511 } 512 513 #[test] 514 fn pl011_input() { 515 let intr_evt = EventFd::new(0).unwrap(); 516 let pl011_out = SharedBuffer::new(); 517 let mut pl011 = Pl011::new( 518 String::from(SERIAL_NAME), 519 Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())), 520 Some(Box::new(pl011_out)), 521 Instant::now(), 522 ); 523 524 // write 1 to the interrupt event fd, so that read doesn't block in case the event fd 525 // counter doesn't change (for 0 it blocks) 526 assert!(intr_evt.write(1).is_ok()); 527 pl011.queue_input_bytes(&[b'a', b'b', b'c']).unwrap(); 528 529 assert_eq!(intr_evt.read().unwrap(), 2); 530 531 let mut data = [0u8]; 532 pl011.read(0, UARTDR as u64, &mut data); 533 assert_eq!(data[0], b'a'); 534 pl011.read(0, UARTDR as u64, &mut data); 535 assert_eq!(data[0], b'b'); 536 pl011.read(0, UARTDR as u64, &mut data); 537 assert_eq!(data[0], b'c'); 538 } 539 } 540