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