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