1 // Copyright 2024, Linaro Limited 2 // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org> 3 // SPDX-License-Identifier: GPL-2.0-or-later 4 5 use std::{ffi::CStr, mem::size_of}; 6 7 use qemu_api::{ 8 chardev::{CharBackend, Chardev, Event}, 9 impl_vmstate_forward, 10 irq::{IRQState, InterruptSource}, 11 log::Log, 12 log_mask_ln, 13 memory::{hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder}, 14 prelude::*, 15 qdev::{Clock, ClockEvent, DeviceImpl, DeviceState, Property, ResetType, ResettablePhasesImpl}, 16 qom::{ObjectImpl, Owned, ParentField, ParentInit}, 17 static_assert, 18 sysbus::{SysBusDevice, SysBusDeviceImpl}, 19 uninit_field_mut, 20 vmstate::VMStateDescription, 21 }; 22 23 use crate::{ 24 device_class, 25 registers::{self, Interrupt, RegisterOffset}, 26 }; 27 28 // TODO: You must disable the UART before any of the control registers are 29 // reprogrammed. When the UART is disabled in the middle of transmission or 30 // reception, it completes the current character before stopping 31 32 /// Integer Baud Rate Divider, `UARTIBRD` 33 const IBRD_MASK: u32 = 0xffff; 34 35 /// Fractional Baud Rate Divider, `UARTFBRD` 36 const FBRD_MASK: u32 = 0x3f; 37 38 /// QEMU sourced constant. 39 pub const PL011_FIFO_DEPTH: u32 = 16; 40 41 #[derive(Clone, Copy)] 42 struct DeviceId(&'static [u8; 8]); 43 44 impl std::ops::Index<hwaddr> for DeviceId { 45 type Output = u8; 46 47 fn index(&self, idx: hwaddr) -> &Self::Output { 48 &self.0[idx as usize] 49 } 50 } 51 52 // FIFOs use 32-bit indices instead of usize, for compatibility with 53 // the migration stream produced by the C version of this device. 54 #[repr(transparent)] 55 #[derive(Debug, Default)] 56 pub struct Fifo([registers::Data; PL011_FIFO_DEPTH as usize]); 57 impl_vmstate_forward!(Fifo); 58 59 impl Fifo { 60 const fn len(&self) -> u32 { 61 self.0.len() as u32 62 } 63 } 64 65 impl std::ops::IndexMut<u32> for Fifo { 66 fn index_mut(&mut self, idx: u32) -> &mut Self::Output { 67 &mut self.0[idx as usize] 68 } 69 } 70 71 impl std::ops::Index<u32> for Fifo { 72 type Output = registers::Data; 73 74 fn index(&self, idx: u32) -> &Self::Output { 75 &self.0[idx as usize] 76 } 77 } 78 79 #[repr(C)] 80 #[derive(Debug, Default)] 81 pub struct PL011Registers { 82 #[doc(alias = "fr")] 83 pub flags: registers::Flags, 84 #[doc(alias = "lcr")] 85 pub line_control: registers::LineControl, 86 #[doc(alias = "rsr")] 87 pub receive_status_error_clear: registers::ReceiveStatusErrorClear, 88 #[doc(alias = "cr")] 89 pub control: registers::Control, 90 pub dmacr: u32, 91 pub int_enabled: Interrupt, 92 pub int_level: Interrupt, 93 pub read_fifo: Fifo, 94 pub ilpr: u32, 95 pub ibrd: u32, 96 pub fbrd: u32, 97 pub ifl: u32, 98 pub read_pos: u32, 99 pub read_count: u32, 100 pub read_trigger: u32, 101 } 102 103 #[repr(C)] 104 #[derive(qemu_api_macros::Object)] 105 /// PL011 Device Model in QEMU 106 pub struct PL011State { 107 pub parent_obj: ParentField<SysBusDevice>, 108 pub iomem: MemoryRegion, 109 #[doc(alias = "chr")] 110 pub char_backend: CharBackend, 111 pub regs: BqlRefCell<PL011Registers>, 112 /// QEMU interrupts 113 /// 114 /// ```text 115 /// * sysbus MMIO region 0: device registers 116 /// * sysbus IRQ 0: `UARTINTR` (combined interrupt line) 117 /// * sysbus IRQ 1: `UARTRXINTR` (receive FIFO interrupt line) 118 /// * sysbus IRQ 2: `UARTTXINTR` (transmit FIFO interrupt line) 119 /// * sysbus IRQ 3: `UARTRTINTR` (receive timeout interrupt line) 120 /// * sysbus IRQ 4: `UARTMSINTR` (momem status interrupt line) 121 /// * sysbus IRQ 5: `UARTEINTR` (error interrupt line) 122 /// ``` 123 #[doc(alias = "irq")] 124 pub interrupts: [InterruptSource; IRQMASK.len()], 125 #[doc(alias = "clk")] 126 pub clock: Owned<Clock>, 127 #[doc(alias = "migrate_clk")] 128 pub migrate_clock: bool, 129 } 130 131 // Some C users of this device embed its state struct into their own 132 // structs, so the size of the Rust version must not be any larger 133 // than the size of the C one. If this assert triggers you need to 134 // expand the padding_for_rust[] array in the C PL011State struct. 135 static_assert!(size_of::<PL011State>() <= size_of::<qemu_api::bindings::PL011State>()); 136 137 qom_isa!(PL011State : SysBusDevice, DeviceState, Object); 138 139 #[repr(C)] 140 pub struct PL011Class { 141 parent_class: <SysBusDevice as ObjectType>::Class, 142 /// The byte string that identifies the device. 143 device_id: DeviceId, 144 } 145 146 trait PL011Impl: SysBusDeviceImpl + IsA<PL011State> { 147 const DEVICE_ID: DeviceId; 148 } 149 150 impl PL011Class { 151 fn class_init<T: PL011Impl>(&mut self) { 152 self.device_id = T::DEVICE_ID; 153 self.parent_class.class_init::<T>(); 154 } 155 } 156 157 unsafe impl ObjectType for PL011State { 158 type Class = PL011Class; 159 const TYPE_NAME: &'static CStr = crate::TYPE_PL011; 160 } 161 162 impl PL011Impl for PL011State { 163 const DEVICE_ID: DeviceId = DeviceId(&[0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1]); 164 } 165 166 impl ObjectImpl for PL011State { 167 type ParentType = SysBusDevice; 168 169 const INSTANCE_INIT: Option<unsafe fn(ParentInit<Self>)> = Some(Self::init); 170 const INSTANCE_POST_INIT: Option<fn(&Self)> = Some(Self::post_init); 171 const CLASS_INIT: fn(&mut Self::Class) = Self::Class::class_init::<Self>; 172 } 173 174 impl DeviceImpl for PL011State { 175 fn properties() -> &'static [Property] { 176 &device_class::PL011_PROPERTIES 177 } 178 fn vmsd() -> Option<&'static VMStateDescription> { 179 Some(&device_class::VMSTATE_PL011) 180 } 181 const REALIZE: Option<fn(&Self) -> qemu_api::Result<()>> = Some(Self::realize); 182 } 183 184 impl ResettablePhasesImpl for PL011State { 185 const HOLD: Option<fn(&Self, ResetType)> = Some(Self::reset_hold); 186 } 187 188 impl SysBusDeviceImpl for PL011State {} 189 190 impl PL011Registers { 191 pub(self) fn read(&mut self, offset: RegisterOffset) -> (bool, u32) { 192 use RegisterOffset::*; 193 194 let mut update = false; 195 let result = match offset { 196 DR => self.read_data_register(&mut update), 197 RSR => u32::from(self.receive_status_error_clear), 198 FR => u32::from(self.flags), 199 FBRD => self.fbrd, 200 ILPR => self.ilpr, 201 IBRD => self.ibrd, 202 LCR_H => u32::from(self.line_control), 203 CR => u32::from(self.control), 204 FLS => self.ifl, 205 IMSC => u32::from(self.int_enabled), 206 RIS => u32::from(self.int_level), 207 MIS => u32::from(self.int_level & self.int_enabled), 208 ICR => { 209 // "The UARTICR Register is the interrupt clear register and is write-only" 210 // Source: ARM DDI 0183G 3.3.13 Interrupt Clear Register, UARTICR 211 0 212 } 213 DMACR => self.dmacr, 214 }; 215 (update, result) 216 } 217 218 pub(self) fn write( 219 &mut self, 220 offset: RegisterOffset, 221 value: u32, 222 char_backend: &CharBackend, 223 ) -> bool { 224 // eprintln!("write offset {offset} value {value}"); 225 use RegisterOffset::*; 226 match offset { 227 DR => return self.write_data_register(value), 228 RSR => { 229 self.receive_status_error_clear = 0.into(); 230 } 231 FR => { 232 // flag writes are ignored 233 } 234 ILPR => { 235 self.ilpr = value; 236 } 237 IBRD => { 238 self.ibrd = value; 239 } 240 FBRD => { 241 self.fbrd = value; 242 } 243 LCR_H => { 244 let new_val: registers::LineControl = value.into(); 245 // Reset the FIFO state on FIFO enable or disable 246 if self.line_control.fifos_enabled() != new_val.fifos_enabled() { 247 self.reset_rx_fifo(); 248 self.reset_tx_fifo(); 249 } 250 let update = (self.line_control.send_break() != new_val.send_break()) && { 251 let break_enable = new_val.send_break(); 252 let _ = char_backend.send_break(break_enable); 253 self.loopback_break(break_enable) 254 }; 255 self.line_control = new_val; 256 self.set_read_trigger(); 257 return update; 258 } 259 CR => { 260 // ??? Need to implement the enable bit. 261 self.control = value.into(); 262 return self.loopback_mdmctrl(); 263 } 264 FLS => { 265 self.ifl = value; 266 self.set_read_trigger(); 267 } 268 IMSC => { 269 self.int_enabled = Interrupt::from(value); 270 return true; 271 } 272 RIS => {} 273 MIS => {} 274 ICR => { 275 self.int_level &= !Interrupt::from(value); 276 return true; 277 } 278 DMACR => { 279 self.dmacr = value; 280 if value & 3 > 0 { 281 log_mask_ln!(Log::Unimp, "pl011: DMA not implemented"); 282 } 283 } 284 } 285 false 286 } 287 288 fn read_data_register(&mut self, update: &mut bool) -> u32 { 289 self.flags.set_receive_fifo_full(false); 290 let c = self.read_fifo[self.read_pos]; 291 292 if self.read_count > 0 { 293 self.read_count -= 1; 294 self.read_pos = (self.read_pos + 1) & (self.fifo_depth() - 1); 295 } 296 if self.read_count == 0 { 297 self.flags.set_receive_fifo_empty(true); 298 } 299 if self.read_count + 1 == self.read_trigger { 300 self.int_level &= !Interrupt::RX; 301 } 302 self.receive_status_error_clear.set_from_data(c); 303 *update = true; 304 u32::from(c) 305 } 306 307 fn write_data_register(&mut self, value: u32) -> bool { 308 if !self.control.enable_uart() { 309 log_mask_ln!(Log::GuestError, "PL011 data written to disabled UART"); 310 } 311 if !self.control.enable_transmit() { 312 log_mask_ln!(Log::GuestError, "PL011 data written to disabled TX UART"); 313 } 314 // interrupts always checked 315 let _ = self.loopback_tx(value.into()); 316 self.int_level |= Interrupt::TX; 317 true 318 } 319 320 #[inline] 321 #[must_use] 322 fn loopback_tx(&mut self, value: registers::Data) -> bool { 323 // Caveat: 324 // 325 // In real hardware, TX loopback happens at the serial-bit level 326 // and then reassembled by the RX logics back into bytes and placed 327 // into the RX fifo. That is, loopback happens after TX fifo. 328 // 329 // Because the real hardware TX fifo is time-drained at the frame 330 // rate governed by the configured serial format, some loopback 331 // bytes in TX fifo may still be able to get into the RX fifo 332 // that could be full at times while being drained at software 333 // pace. 334 // 335 // In such scenario, the RX draining pace is the major factor 336 // deciding which loopback bytes get into the RX fifo, unless 337 // hardware flow-control is enabled. 338 // 339 // For simplicity, the above described is not emulated. 340 self.loopback_enabled() && self.fifo_rx_put(value) 341 } 342 343 #[must_use] 344 fn loopback_mdmctrl(&mut self) -> bool { 345 if !self.loopback_enabled() { 346 return false; 347 } 348 349 /* 350 * Loopback software-driven modem control outputs to modem status inputs: 351 * FR.RI <= CR.Out2 352 * FR.DCD <= CR.Out1 353 * FR.CTS <= CR.RTS 354 * FR.DSR <= CR.DTR 355 * 356 * The loopback happens immediately even if this call is triggered 357 * by setting only CR.LBE. 358 * 359 * CTS/RTS updates due to enabled hardware flow controls are not 360 * dealt with here. 361 */ 362 363 self.flags.set_ring_indicator(self.control.out_2()); 364 self.flags.set_data_carrier_detect(self.control.out_1()); 365 self.flags.set_clear_to_send(self.control.request_to_send()); 366 self.flags 367 .set_data_set_ready(self.control.data_transmit_ready()); 368 369 // Change interrupts based on updated FR 370 let mut il = self.int_level; 371 372 il &= !Interrupt::MS; 373 374 if self.flags.data_set_ready() { 375 il |= Interrupt::DSR; 376 } 377 if self.flags.data_carrier_detect() { 378 il |= Interrupt::DCD; 379 } 380 if self.flags.clear_to_send() { 381 il |= Interrupt::CTS; 382 } 383 if self.flags.ring_indicator() { 384 il |= Interrupt::RI; 385 } 386 self.int_level = il; 387 true 388 } 389 390 fn loopback_break(&mut self, enable: bool) -> bool { 391 enable && self.loopback_tx(registers::Data::BREAK) 392 } 393 394 fn set_read_trigger(&mut self) { 395 self.read_trigger = 1; 396 } 397 398 pub fn reset(&mut self) { 399 self.line_control.reset(); 400 self.receive_status_error_clear.reset(); 401 self.dmacr = 0; 402 self.int_enabled = 0.into(); 403 self.int_level = 0.into(); 404 self.ilpr = 0; 405 self.ibrd = 0; 406 self.fbrd = 0; 407 self.read_trigger = 1; 408 self.ifl = 0x12; 409 self.control.reset(); 410 self.flags.reset(); 411 self.reset_rx_fifo(); 412 self.reset_tx_fifo(); 413 } 414 415 pub fn reset_rx_fifo(&mut self) { 416 self.read_count = 0; 417 self.read_pos = 0; 418 419 // Reset FIFO flags 420 self.flags.set_receive_fifo_full(false); 421 self.flags.set_receive_fifo_empty(true); 422 } 423 424 pub fn reset_tx_fifo(&mut self) { 425 // Reset FIFO flags 426 self.flags.set_transmit_fifo_full(false); 427 self.flags.set_transmit_fifo_empty(true); 428 } 429 430 #[inline] 431 pub fn fifo_enabled(&self) -> bool { 432 self.line_control.fifos_enabled() == registers::Mode::FIFO 433 } 434 435 #[inline] 436 pub fn loopback_enabled(&self) -> bool { 437 self.control.enable_loopback() 438 } 439 440 #[inline] 441 pub fn fifo_depth(&self) -> u32 { 442 // Note: FIFO depth is expected to be power-of-2 443 if self.fifo_enabled() { 444 return PL011_FIFO_DEPTH; 445 } 446 1 447 } 448 449 #[must_use] 450 pub fn fifo_rx_put(&mut self, value: registers::Data) -> bool { 451 let depth = self.fifo_depth(); 452 assert!(depth > 0); 453 let slot = (self.read_pos + self.read_count) & (depth - 1); 454 self.read_fifo[slot] = value; 455 self.read_count += 1; 456 self.flags.set_receive_fifo_empty(false); 457 if self.read_count == depth { 458 self.flags.set_receive_fifo_full(true); 459 } 460 461 if self.read_count == self.read_trigger { 462 self.int_level |= Interrupt::RX; 463 return true; 464 } 465 false 466 } 467 468 pub fn post_load(&mut self) -> Result<(), ()> { 469 /* Sanity-check input state */ 470 if self.read_pos >= self.read_fifo.len() || self.read_count > self.read_fifo.len() { 471 return Err(()); 472 } 473 474 if !self.fifo_enabled() && self.read_count > 0 && self.read_pos > 0 { 475 // Older versions of PL011 didn't ensure that the single 476 // character in the FIFO in FIFO-disabled mode is in 477 // element 0 of the array; convert to follow the current 478 // code's assumptions. 479 self.read_fifo[0] = self.read_fifo[self.read_pos]; 480 self.read_pos = 0; 481 } 482 483 self.ibrd &= IBRD_MASK; 484 self.fbrd &= FBRD_MASK; 485 486 Ok(()) 487 } 488 } 489 490 impl PL011State { 491 /// Initializes a pre-allocated, uninitialized instance of `PL011State`. 492 /// 493 /// # Safety 494 /// 495 /// `self` must point to a correctly sized and aligned location for the 496 /// `PL011State` type. It must not be called more than once on the same 497 /// location/instance. All its fields are expected to hold uninitialized 498 /// values with the sole exception of `parent_obj`. 499 unsafe fn init(mut this: ParentInit<Self>) { 500 static PL011_OPS: MemoryRegionOps<PL011State> = MemoryRegionOpsBuilder::<PL011State>::new() 501 .read(&PL011State::read) 502 .write(&PL011State::write) 503 .native_endian() 504 .impl_sizes(4, 4) 505 .build(); 506 507 // SAFETY: this and this.iomem are guaranteed to be valid at this point 508 MemoryRegion::init_io( 509 &mut uninit_field_mut!(*this, iomem), 510 &PL011_OPS, 511 "pl011", 512 0x1000, 513 ); 514 515 uninit_field_mut!(*this, regs).write(Default::default()); 516 517 let clock = DeviceState::init_clock_in( 518 &mut this, 519 "clk", 520 &Self::clock_update, 521 ClockEvent::ClockUpdate, 522 ); 523 uninit_field_mut!(*this, clock).write(clock); 524 } 525 526 const fn clock_update(&self, _event: ClockEvent) { 527 /* pl011_trace_baudrate_change(s); */ 528 } 529 530 fn post_init(&self) { 531 self.init_mmio(&self.iomem); 532 for irq in self.interrupts.iter() { 533 self.init_irq(irq); 534 } 535 } 536 537 fn read(&self, offset: hwaddr, _size: u32) -> u64 { 538 match RegisterOffset::try_from(offset) { 539 Err(v) if (0x3f8..0x400).contains(&(v >> 2)) => { 540 let device_id = self.get_class().device_id; 541 u64::from(device_id[(offset - 0xfe0) >> 2]) 542 } 543 Err(_) => { 544 log_mask_ln!(Log::GuestError, "PL011State::read: Bad offset {offset}"); 545 0 546 } 547 Ok(field) => { 548 let (update_irq, result) = self.regs.borrow_mut().read(field); 549 if update_irq { 550 self.update(); 551 self.char_backend.accept_input(); 552 } 553 result.into() 554 } 555 } 556 } 557 558 fn write(&self, offset: hwaddr, value: u64, _size: u32) { 559 let mut update_irq = false; 560 if let Ok(field) = RegisterOffset::try_from(offset) { 561 // qemu_chr_fe_write_all() calls into the can_receive 562 // callback, so handle writes before entering PL011Registers. 563 if field == RegisterOffset::DR { 564 // ??? Check if transmitter is enabled. 565 let ch: [u8; 1] = [value as u8]; 566 // XXX this blocks entire thread. Rewrite to use 567 // qemu_chr_fe_write and background I/O callbacks 568 let _ = self.char_backend.write_all(&ch); 569 } 570 571 update_irq = self 572 .regs 573 .borrow_mut() 574 .write(field, value as u32, &self.char_backend); 575 } else { 576 log_mask_ln!( 577 Log::GuestError, 578 "PL011State::write: Bad offset {offset} value {value}" 579 ); 580 } 581 if update_irq { 582 self.update(); 583 } 584 } 585 586 fn can_receive(&self) -> u32 { 587 let regs = self.regs.borrow(); 588 // trace_pl011_can_receive(s->lcr, s->read_count, r); 589 regs.fifo_depth() - regs.read_count 590 } 591 592 fn receive(&self, buf: &[u8]) { 593 let mut regs = self.regs.borrow_mut(); 594 if regs.loopback_enabled() { 595 // In loopback mode, the RX input signal is internally disconnected 596 // from the entire receiving logics; thus, all inputs are ignored, 597 // and BREAK detection on RX input signal is also not performed. 598 return; 599 } 600 601 let mut update_irq = false; 602 for &c in buf { 603 let c: u32 = c.into(); 604 update_irq |= regs.fifo_rx_put(c.into()); 605 } 606 607 // Release the BqlRefCell before calling self.update() 608 drop(regs); 609 if update_irq { 610 self.update(); 611 } 612 } 613 614 fn event(&self, event: Event) { 615 let mut update_irq = false; 616 let mut regs = self.regs.borrow_mut(); 617 if event == Event::CHR_EVENT_BREAK && !regs.loopback_enabled() { 618 update_irq = regs.fifo_rx_put(registers::Data::BREAK); 619 } 620 // Release the BqlRefCell before calling self.update() 621 drop(regs); 622 623 if update_irq { 624 self.update() 625 } 626 } 627 628 fn realize(&self) -> qemu_api::Result<()> { 629 self.char_backend 630 .enable_handlers(self, Self::can_receive, Self::receive, Self::event); 631 Ok(()) 632 } 633 634 fn reset_hold(&self, _type: ResetType) { 635 self.regs.borrow_mut().reset(); 636 } 637 638 fn update(&self) { 639 let regs = self.regs.borrow(); 640 let flags = regs.int_level & regs.int_enabled; 641 for (irq, i) in self.interrupts.iter().zip(IRQMASK) { 642 irq.set(flags.any_set(i)); 643 } 644 } 645 646 pub fn post_load(&self, _version_id: u32) -> Result<(), ()> { 647 self.regs.borrow_mut().post_load() 648 } 649 } 650 651 /// Which bits in the interrupt status matter for each outbound IRQ line ? 652 const IRQMASK: [Interrupt; 6] = [ 653 Interrupt::all(), 654 Interrupt::RX, 655 Interrupt::TX, 656 Interrupt::RT, 657 Interrupt::MS, 658 Interrupt::E, 659 ]; 660 661 /// # Safety 662 /// 663 /// We expect the FFI user of this function to pass a valid pointer for `chr` 664 /// and `irq`. 665 #[no_mangle] 666 pub unsafe extern "C" fn pl011_create( 667 addr: u64, 668 irq: *mut IRQState, 669 chr: *mut Chardev, 670 ) -> *mut DeviceState { 671 // SAFETY: The callers promise that they have owned references. 672 // They do not gift them to pl011_create, so use `Owned::from`. 673 let irq = unsafe { Owned::<IRQState>::from(&*irq) }; 674 675 let dev = PL011State::new(); 676 if !chr.is_null() { 677 let chr = unsafe { Owned::<Chardev>::from(&*chr) }; 678 dev.prop_set_chr("chardev", &chr); 679 } 680 dev.sysbus_realize(); 681 dev.mmio_map(0, addr); 682 dev.connect_irq(0, &irq); 683 684 // The pointer is kept alive by the QOM tree; drop the owned ref 685 dev.as_mut_ptr() 686 } 687 688 #[repr(C)] 689 #[derive(qemu_api_macros::Object)] 690 /// PL011 Luminary device model. 691 pub struct PL011Luminary { 692 parent_obj: ParentField<PL011State>, 693 } 694 695 qom_isa!(PL011Luminary : PL011State, SysBusDevice, DeviceState, Object); 696 697 unsafe impl ObjectType for PL011Luminary { 698 type Class = <PL011State as ObjectType>::Class; 699 const TYPE_NAME: &'static CStr = crate::TYPE_PL011_LUMINARY; 700 } 701 702 impl ObjectImpl for PL011Luminary { 703 type ParentType = PL011State; 704 705 const CLASS_INIT: fn(&mut Self::Class) = Self::Class::class_init::<Self>; 706 } 707 708 impl PL011Impl for PL011Luminary { 709 const DEVICE_ID: DeviceId = DeviceId(&[0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1]); 710 } 711 712 impl DeviceImpl for PL011Luminary {} 713 impl ResettablePhasesImpl for PL011Luminary {} 714 impl SysBusDeviceImpl for PL011Luminary {} 715