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 state: Option<Pl011State>, 126 ) -> Self { 127 let ( 128 flags, 129 lcr, 130 rsr, 131 cr, 132 dmacr, 133 debug, 134 int_enabled, 135 int_level, 136 read_fifo, 137 ilpr, 138 ibrd, 139 fbrd, 140 ifl, 141 read_count, 142 read_trigger, 143 ) = if let Some(state) = state { 144 ( 145 state.flags, 146 state.lcr, 147 state.rsr, 148 state.cr, 149 state.dmacr, 150 state.debug, 151 state.int_enabled, 152 state.int_level, 153 state.read_fifo.into(), 154 state.ilpr, 155 state.ibrd, 156 state.fbrd, 157 state.ifl, 158 state.read_count, 159 state.read_trigger, 160 ) 161 } else { 162 ( 163 0x90, 164 0, 165 0, 166 0x300, 167 0, 168 0, 169 0, 170 0, 171 VecDeque::new(), 172 0, 173 0, 174 0, 175 0x12, 176 0, 177 1, 178 ) 179 }; 180 181 Self { 182 id, 183 flags, 184 lcr, 185 rsr, 186 cr, 187 dmacr, 188 debug, 189 int_enabled, 190 int_level, 191 read_fifo, 192 ilpr, 193 ibrd, 194 fbrd, 195 ifl, 196 read_count, 197 read_trigger, 198 irq, 199 out, 200 timestamp, 201 } 202 } 203 204 pub fn set_out(&mut self, out: Option<Box<dyn io::Write + Send>>) { 205 self.out = out; 206 } 207 208 fn state(&self) -> Pl011State { 209 Pl011State { 210 flags: self.flags, 211 lcr: self.lcr, 212 rsr: self.rsr, 213 cr: self.cr, 214 dmacr: self.dmacr, 215 debug: self.debug, 216 int_enabled: self.int_enabled, 217 int_level: self.int_level, 218 read_fifo: self.read_fifo.clone().into(), 219 ilpr: self.ilpr, 220 ibrd: self.ibrd, 221 fbrd: self.fbrd, 222 ifl: self.ifl, 223 read_count: self.read_count, 224 read_trigger: self.read_trigger, 225 } 226 } 227 228 /// Queues raw bytes for the guest to read and signals the interrupt 229 pub fn queue_input_bytes(&mut self, c: &[u8]) -> vmm_sys_util::errno::Result<()> { 230 self.read_fifo.extend(c); 231 self.read_count += c.len() as u32; 232 self.flags &= !PL011_FLAG_RXFE; 233 234 if ((self.lcr & 0x10) == 0) || (self.read_count == 16) { 235 self.flags |= PL011_FLAG_RXFF; 236 } 237 238 if self.read_count >= self.read_trigger { 239 self.int_level |= PL011_INT_RX; 240 self.trigger_interrupt()?; 241 } 242 243 Ok(()) 244 } 245 246 pub fn flush_output(&mut self) -> result::Result<(), io::Error> { 247 if let Some(out) = self.out.as_mut() { 248 out.flush()?; 249 } 250 Ok(()) 251 } 252 253 fn pl011_get_baudrate(&self) -> u32 { 254 if self.fbrd == 0 { 255 return 0; 256 } 257 258 let clk = 24_000_000; // We set the APB_PLCK to 24M in device tree 259 (clk / ((self.ibrd << 6) + self.fbrd)) << 2 260 } 261 262 fn pl011_trace_baudrate_change(&self) { 263 debug!( 264 "=== New baudrate: {:#?} (clk: {:#?}Hz, ibrd: {:#?}, fbrd: {:#?}) ===", 265 self.pl011_get_baudrate(), 266 24_000_000, // We set the APB_PLCK to 24M in device tree 267 self.ibrd, 268 self.fbrd 269 ); 270 } 271 272 fn pl011_set_read_trigger(&mut self) { 273 self.read_trigger = 1; 274 } 275 276 fn handle_write(&mut self, offset: u64, val: u32) -> Result<()> { 277 match offset >> 2 { 278 UARTDR => { 279 self.int_level |= PL011_INT_TX; 280 if let Some(out) = self.out.as_mut() { 281 out.write_all(&[val.to_le_bytes()[0]]) 282 .map_err(Error::WriteAllFailure)?; 283 out.flush().map_err(Error::FlushFailure)?; 284 } 285 } 286 UARTRSR_UARTECR => { 287 self.rsr = 0; 288 } 289 UARTFR => { /* Writes to Flag register are ignored.*/ } 290 UARTILPR => { 291 self.ilpr = val; 292 } 293 UARTIBRD => { 294 self.ibrd = val; 295 self.pl011_trace_baudrate_change(); 296 } 297 UARTFBRD => { 298 self.fbrd = val; 299 self.pl011_trace_baudrate_change(); 300 } 301 UARTLCR_H => { 302 /* Reset the FIFO state on FIFO enable or disable */ 303 if ((self.lcr ^ val) & 0x10) != 0 { 304 self.read_count = 0; 305 } 306 self.lcr = val; 307 self.pl011_set_read_trigger(); 308 } 309 UARTCR => { 310 self.cr = val; 311 } 312 UARTIFLS => { 313 self.ifl = val; 314 self.pl011_set_read_trigger(); 315 } 316 UARTIMSC => { 317 self.int_enabled = val; 318 self.trigger_interrupt().map_err(Error::InterruptFailure)?; 319 } 320 UARTICR => { 321 self.int_level &= !val; 322 self.trigger_interrupt().map_err(Error::InterruptFailure)?; 323 } 324 UARTDMACR => { 325 self.dmacr = val; 326 if (val & 3) != 0 { 327 return Err(Error::DmaNotImplemented); 328 } 329 } 330 UARTDEBUG => { 331 self.debug = val; 332 self.handle_debug(); 333 } 334 off => { 335 debug!("PL011: Bad write offset, offset: {}", off); 336 return Err(Error::BadWriteOffset(off)); 337 } 338 } 339 Ok(()) 340 } 341 342 fn handle_debug(&self) { 343 let elapsed = self.timestamp.elapsed(); 344 345 match self.debug { 346 0x00..=0x1f => warn!( 347 "[Debug I/O port: Firmware code: 0x{:x}] {}.{:>06} seconds", 348 self.debug, 349 elapsed.as_secs(), 350 elapsed.as_micros() 351 ), 352 0x20..=0x3f => warn!( 353 "[Debug I/O port: Bootloader code: 0x{:x}] {}.{:>06} seconds", 354 self.debug, 355 elapsed.as_secs(), 356 elapsed.as_micros() 357 ), 358 0x40..=0x5f => warn!( 359 "[Debug I/O port: Kernel code: 0x{:x}] {}.{:>06} seconds", 360 self.debug, 361 elapsed.as_secs(), 362 elapsed.as_micros() 363 ), 364 0x60..=0x7f => warn!( 365 "[Debug I/O port: Userspace code: 0x{:x}] {}.{:>06} seconds", 366 self.debug, 367 elapsed.as_secs(), 368 elapsed.as_micros() 369 ), 370 _ => {} 371 } 372 } 373 374 fn trigger_interrupt(&mut self) -> result::Result<(), io::Error> { 375 self.irq.trigger(0) 376 } 377 } 378 379 impl BusDevice for Pl011 { 380 fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) { 381 let mut read_ok = true; 382 let v = if (AMBA_ID_LOW..AMBA_ID_HIGH).contains(&(offset >> 2)) { 383 let index = ((offset - 0xfe0) >> 2) as usize; 384 u32::from(PL011_ID[index]) 385 } else { 386 match offset >> 2 { 387 UARTDR => { 388 self.flags &= !PL011_FLAG_RXFF; 389 let c: u32 = self.read_fifo.pop_front().unwrap_or_default().into(); 390 if self.read_count > 0 { 391 self.read_count -= 1; 392 } 393 if self.read_count == 0 { 394 self.flags |= PL011_FLAG_RXFE; 395 } 396 if self.read_count == (self.read_trigger - 1) { 397 self.int_level &= !PL011_INT_RX; 398 } 399 self.rsr = c >> 8; 400 c 401 } 402 UARTRSR_UARTECR => self.rsr, 403 UARTFR => self.flags, 404 UARTILPR => self.ilpr, 405 UARTIBRD => self.ibrd, 406 UARTFBRD => self.fbrd, 407 UARTLCR_H => self.lcr, 408 UARTCR => self.cr, 409 UARTIFLS => self.ifl, 410 UARTIMSC => self.int_enabled, 411 UARTRIS => self.int_level, 412 UARTMIS => self.int_level & self.int_enabled, 413 UARTDMACR => self.dmacr, 414 UARTDEBUG => self.debug, 415 _ => { 416 read_ok = false; 417 0 418 } 419 } 420 }; 421 422 if read_ok && data.len() <= 4 { 423 write_le_u32(data, v); 424 } else { 425 warn!( 426 "Invalid PL011 read: offset {}, data length {}", 427 offset, 428 data.len() 429 ); 430 } 431 } 432 433 fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> { 434 if data.len() <= 4 { 435 let v = read_le_u32(data); 436 if let Err(e) = self.handle_write(offset, v) { 437 warn!("Failed to write to PL011 device: {}", e); 438 } 439 } else { 440 warn!( 441 "Invalid PL011 write: offset {}, data length {}", 442 offset, 443 data.len() 444 ); 445 } 446 447 None 448 } 449 } 450 451 impl Snapshottable for Pl011 { 452 fn id(&self) -> String { 453 self.id.clone() 454 } 455 456 fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> { 457 Snapshot::new_from_versioned_state(&self.state()) 458 } 459 } 460 461 impl Pausable for Pl011 {} 462 impl Transportable for Pl011 {} 463 impl Migratable for Pl011 {} 464 465 #[cfg(test)] 466 mod tests { 467 use super::*; 468 use std::sync::Mutex; 469 use vm_device::interrupt::{InterruptIndex, InterruptSourceConfig}; 470 use vmm_sys_util::eventfd::EventFd; 471 472 const SERIAL_NAME: &str = "serial"; 473 474 struct TestInterrupt { 475 event_fd: EventFd, 476 } 477 478 impl InterruptSourceGroup for TestInterrupt { 479 fn trigger(&self, _index: InterruptIndex) -> result::Result<(), std::io::Error> { 480 self.event_fd.write(1) 481 } 482 fn update( 483 &self, 484 _index: InterruptIndex, 485 _config: InterruptSourceConfig, 486 _masked: bool, 487 _set_gsi: bool, 488 ) -> result::Result<(), std::io::Error> { 489 Ok(()) 490 } 491 fn set_gsi(&self) -> result::Result<(), std::io::Error> { 492 Ok(()) 493 } 494 fn notifier(&self, _index: InterruptIndex) -> Option<EventFd> { 495 Some(self.event_fd.try_clone().unwrap()) 496 } 497 } 498 499 impl TestInterrupt { 500 fn new(event_fd: EventFd) -> Self { 501 TestInterrupt { event_fd } 502 } 503 } 504 505 #[derive(Clone)] 506 struct SharedBuffer { 507 buf: Arc<Mutex<Vec<u8>>>, 508 } 509 510 impl SharedBuffer { 511 fn new() -> SharedBuffer { 512 SharedBuffer { 513 buf: Arc::new(Mutex::new(Vec::new())), 514 } 515 } 516 } 517 518 impl io::Write for SharedBuffer { 519 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 520 self.buf.lock().unwrap().write(buf) 521 } 522 fn flush(&mut self) -> io::Result<()> { 523 self.buf.lock().unwrap().flush() 524 } 525 } 526 527 #[test] 528 fn pl011_output() { 529 let intr_evt = EventFd::new(0).unwrap(); 530 let pl011_out = SharedBuffer::new(); 531 let mut pl011 = Pl011::new( 532 String::from(SERIAL_NAME), 533 Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())), 534 Some(Box::new(pl011_out.clone())), 535 Instant::now(), 536 None, 537 ); 538 539 pl011.write(0, UARTDR, &[b'x', b'y']); 540 pl011.write(0, UARTDR, &[b'a']); 541 pl011.write(0, UARTDR, &[b'b']); 542 pl011.write(0, UARTDR, &[b'c']); 543 assert_eq!( 544 pl011_out.buf.lock().unwrap().as_slice(), 545 &[b'x', b'a', b'b', b'c'] 546 ); 547 } 548 549 #[test] 550 fn pl011_input() { 551 let intr_evt = EventFd::new(0).unwrap(); 552 let pl011_out = SharedBuffer::new(); 553 let mut pl011 = Pl011::new( 554 String::from(SERIAL_NAME), 555 Arc::new(TestInterrupt::new(intr_evt.try_clone().unwrap())), 556 Some(Box::new(pl011_out)), 557 Instant::now(), 558 None, 559 ); 560 561 // write 1 to the interrupt event fd, so that read doesn't block in case the event fd 562 // counter doesn't change (for 0 it blocks) 563 assert!(intr_evt.write(1).is_ok()); 564 pl011.queue_input_bytes(&[b'a', b'b', b'c']).unwrap(); 565 566 assert_eq!(intr_evt.read().unwrap(), 2); 567 568 let mut data = [0u8]; 569 pl011.read(0, UARTDR, &mut data); 570 assert_eq!(data[0], b'a'); 571 pl011.read(0, UARTDR, &mut data); 572 assert_eq!(data[0], b'b'); 573 pl011.read(0, UARTDR, &mut data); 574 assert_eq!(data[0], b'c'); 575 } 576 } 577