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