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