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