diff options
| author | Richard Henderson <richard.henderson@linaro.org> | 2025-10-01 15:02:42 -0700 |
|---|---|---|
| committer | Richard Henderson <richard.henderson@linaro.org> | 2025-10-01 15:02:42 -0700 |
| commit | 1abdde1ad42d0ebccc5e8bc574ebe805cd650102 (patch) | |
| tree | 5235492f2c75ce86b824a11dd9a41bc2560df826 /rust/hw/char/pl011/src | |
| parent | f665537f1543050cb9e756d4affff10cdf92b7ed (diff) | |
| parent | 1461752f0fa4bcd7e60d51fe47e3430f8a81cdd8 (diff) | |
| download | focaccia-qemu-1abdde1ad42d0ebccc5e8bc574ebe805cd650102.tar.gz focaccia-qemu-1abdde1ad42d0ebccc5e8bc574ebe805cd650102.zip | |
Merge tag 'tracing-pull-request' of https://gitlab.com/stefanha/qemu into staging
Pull request Tanish Desai and Paolo Bonzini's tracing Rust support. # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCgAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAmjdSSIACgkQnKSrs4Gr # c8h8hwf/RXawMzImGn3I2kTOUWAQ97+yY0UgtyO010K71gypBa2EBcPIVH0ZOsy0 # oT5pF2w7k0g83DXqupXiZO3yjSSmeGBXlOw8QS6D+FN0VpsdxrYJnvzVMqCckOrR # 6wwM+fYYfCk/LwQFvjcMDdd6BSB/wUyMuBnh+fa8X9vxRL6CgMY7RpQd7YZ9JNtL # PFQscu/K6zUARxwQ/DZTx5jYlW4rE5O4mq80CW2l1pgnyOH5vH/TySTKp0yX8eDO # 5eoF7ttieOxxt6YobFak7EfWFvFuyp1j5NlWlyWKzhce1oSOAbaXnB1I61admRb3 # 7XrsTU0RjH6kp8ki4SZEoAh/HMw+4w== # =myWt # -----END PGP SIGNATURE----- # gpg: Signature made Wed 01 Oct 2025 08:30:42 AM PDT # gpg: using RSA key 8695A8BFD3F97CDAAC35775A9CA4ABB381AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" [unknown] # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8 * tag 'tracing-pull-request' of https://gitlab.com/stefanha/qemu: tracetool/syslog: add Rust support tracetool/ftrace: add Rust support tracetool/log: add Rust support log: change qemu_loglevel to unsigned tracetool/simple: add Rust support rust: pl011: add tracepoints rust: qdev: add minimal clock bindings rust: add trace crate tracetool: Add Rust format support tracetool/backend: remove redundant trace event checks tracetool: add CHECK_TRACE_EVENT_GET_STATE trace/ftrace: move snprintf+write from tracepoints to ftrace.c tracetool: add SPDX headers treewide: remove unnessary "coding" header tracetool: remove dead code tracetool: fix usage of try_import() Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'rust/hw/char/pl011/src')
| -rw-r--r-- | rust/hw/char/pl011/src/device.rs | 57 |
1 files changed, 40 insertions, 17 deletions
diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 1b4587d5f6..8889d6e54f 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -21,6 +21,8 @@ use util::{log::Log, log_mask_ln}; use crate::registers::{self, Interrupt, RegisterOffset}; +::trace::include_trace!("hw_char"); + // TODO: You must disable the UART before any of the control registers are // reprogrammed. When the UART is disabled in the middle of transmission or // reception, it completes the current character before stopping @@ -208,13 +210,7 @@ impl PL011Registers { (update, result) } - pub(self) fn write( - &mut self, - offset: RegisterOffset, - value: u32, - char_backend: &CharBackend, - ) -> bool { - // eprintln!("write offset {offset} value {value}"); + pub(self) fn write(&mut self, offset: RegisterOffset, value: u32, device: &PL011State) -> bool { use RegisterOffset::*; match offset { DR => return self.write_data_register(value), @@ -229,9 +225,11 @@ impl PL011Registers { } IBRD => { self.ibrd = value; + device.trace_baudrate_change(self.ibrd, self.fbrd); } FBRD => { self.fbrd = value; + device.trace_baudrate_change(self.ibrd, self.fbrd); } LCR_H => { let new_val: registers::LineControl = value.into(); @@ -242,7 +240,7 @@ impl PL011Registers { } let update = (self.line_control.send_break() != new_val.send_break()) && { let break_enable = new_val.send_break(); - let _ = char_backend.send_break(break_enable); + let _ = device.char_backend.send_break(break_enable); self.loopback_break(break_enable) }; self.line_control = new_val; @@ -279,12 +277,13 @@ impl PL011Registers { } fn read_data_register(&mut self, update: &mut bool) -> u32 { + let depth = self.fifo_depth(); self.flags.set_receive_fifo_full(false); let c = self.read_fifo[self.read_pos]; if self.read_count > 0 { self.read_count -= 1; - self.read_pos = (self.read_pos + 1) & (self.fifo_depth() - 1); + self.read_pos = (self.read_pos + 1) & (depth - 1); } if self.read_count == 0 { self.flags.set_receive_fifo_empty(true); @@ -292,6 +291,7 @@ impl PL011Registers { if self.read_count + 1 == self.read_trigger { self.int_level &= !Interrupt::RX; } + trace::trace_pl011_read_fifo(self.read_count, depth); self.receive_status_error_clear.set_from_data(c); *update = true; u32::from(c) @@ -447,7 +447,9 @@ impl PL011Registers { self.read_fifo[slot] = value; self.read_count += 1; self.flags.set_receive_fifo_empty(false); + trace::trace_pl011_fifo_rx_put(value.into(), self.read_count, depth); if self.read_count == depth { + trace::trace_pl011_fifo_rx_full(); self.flags.set_receive_fifo_full(true); } @@ -516,8 +518,21 @@ impl PL011State { uninit_field_mut!(*this, clock).write(clock); } - const fn clock_update(&self, _event: ClockEvent) { - /* pl011_trace_baudrate_change(s); */ + pub fn trace_baudrate_change(&self, ibrd: u32, fbrd: u32) { + let divider = 4.0 / f64::from(ibrd * (FBRD_MASK + 1) + fbrd); + let hz = self.clock.hz(); + let rate = if ibrd == 0 { + 0 + } else { + ((hz as f64) * divider) as u32 + }; + trace::trace_pl011_baudrate_change(rate, hz, ibrd, fbrd); + } + + fn clock_update(&self, _event: ClockEvent) { + let regs = self.regs.borrow(); + let (ibrd, fbrd) = (regs.ibrd, regs.fbrd); + self.trace_baudrate_change(ibrd, fbrd) } pub fn clock_needed(&self) -> bool { @@ -543,6 +558,7 @@ impl PL011State { } Ok(field) => { let (update_irq, result) = self.regs.borrow_mut().read(field); + trace::trace_pl011_read(offset, result, c""); if update_irq { self.update(); self.char_backend.accept_input(); @@ -557,6 +573,7 @@ impl PL011State { if let Ok(field) = RegisterOffset::try_from(offset) { // qemu_chr_fe_write_all() calls into the can_receive // callback, so handle writes before entering PL011Registers. + trace::trace_pl011_write(offset, value as u32, c""); if field == RegisterOffset::DR { // ??? Check if transmitter is enabled. let ch: [u8; 1] = [value as u8]; @@ -565,10 +582,7 @@ impl PL011State { let _ = self.char_backend.write_all(&ch); } - update_irq = self - .regs - .borrow_mut() - .write(field, value as u32, &self.char_backend); + update_irq = self.regs.borrow_mut().write(field, value as u32, self); } else { log_mask_ln!( Log::GuestError, @@ -582,11 +596,19 @@ impl PL011State { fn can_receive(&self) -> u32 { let regs = self.regs.borrow(); - // trace_pl011_can_receive(s->lcr, s->read_count, r); - regs.fifo_depth() - regs.read_count + let fifo_available = regs.fifo_depth() - regs.read_count; + trace::trace_pl011_can_receive( + regs.line_control.into(), + regs.read_count, + regs.fifo_depth(), + fifo_available, + ); + fifo_available } fn receive(&self, buf: &[u8]) { + trace::trace_pl011_receive(buf.len()); + let mut regs = self.regs.borrow_mut(); if regs.loopback_enabled() { // In loopback mode, the RX input signal is internally disconnected @@ -635,6 +657,7 @@ impl PL011State { fn update(&self) { let regs = self.regs.borrow(); let flags = regs.int_level & regs.int_enabled; + trace::trace_pl011_irq_state(flags != 0); for (irq, i) in self.interrupts.iter().zip(IRQMASK) { irq.set(flags.any_set(i)); } |