qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] rust: Add HPET timer device
@ 2025-01-25 12:51 Zhao Liu
  2025-01-25 12:51 ` [PATCH 01/10] i386/fw_cfg: move hpet_cfg definition to hpet.c Zhao Liu
                   ` (9 more replies)
  0 siblings, 10 replies; 34+ messages in thread
From: Zhao Liu @ 2025-01-25 12:51 UTC (permalink / raw)
  To: Paolo Bonzini, Manos Pitsidianakis, Junjie Mao, Alex Bennée,
	Philippe Mathieu-Daudé, Richard Henderson, Peter Maydell,
	Daniel P . Berrangé
  Cc: qemu-devel, qemu-rust, Zhao Liu

Hi folks,

This is Rust HPET normal patch series, and you can find the previous RFC
at [1].

This series is based on Paolo's rust-next branch at the commit
441f501bc611 ("rust: bindings for MemoryRegionOps") along with 2
seperate patches:

* https://lore.kernel.org/qemu-devel/20241205203721.347233-1-pbonzini@redhat.com/
* https://lore.kernel.org/qemu-devel/20250121140121.84550-1-zhao1.liu@intel.com/

Overall, HPET in Rust maintains the same logic as the original C
version, adhering to the Intel IA PC-HPET spec v1.0a [2]. While keeping
the logic unchanged, it attempts to keep up with the current development
progress of Rust for QEMU, leveraging the latest and ongoing Rust binding
updates as much as possible, such as BqlCell / BqlRefCell, qom & qdev
enhancements, irq binding, and more.

*** This series further utilizes bitops, callback, memory, and Resettable
bindings compared to the RFC. ***

Additionally, it introduces new bindings, including gpio_{in|out},
memattrs, and timer.

What surprised me was that while working on this version of the patch, I
clearly felt the improvements in Rust QOM and QAPI. They are much more
user-friendly in many ways. :-) Almost everything related with API has
been simplified a lot!

(At the end of this cover letter, I briefly talked about my thoughts as
I was once again faced with the choice between BqlCell and BqlRefCell.)


Welcome your comments and feedback!


Introduction
============

.
│ 
...
└── timer
    ├── hpet
    │   ├── Cargo.toml
    │   ├── meson.build
    │   └── src
    │       ├── fw_cfg.rs
    │       ├── hpet.rs
    │       ├── lib.rs
    ├── Kconfig
    └── meson.build


HPET emulation contains 2 parts:
 * HPET device emulation:
   - hpet.rs:
     It includes basic operations for the HPET timer and HPET state
     (which actually represents the HPET timer block).

     Here, similar to the C implementation, it directly defines the
     registers and bit shifts as const variables, without a complete
     register space structure.

     And, it implements various QEMU qdev/qom required traits for the
     HPETState.

 * Global HPET firmwrie configuration:
   - fw_cfg.rs
     In the C code, there is a variable hpet_fw_cfg (old name: hpet_cfg)
     used to configure the number of HPET timer blocks and the basic
     HPET firmware configuration. It is defined in .c file and is
     referenced as extern in the .h file.

     For the Rust HPET, fw_cfg.rs also implementes hpet_fw_cfg so that
     the .h file can still reference it.


Next Work
=========

* vmstate support.
  - Utilize the recent vmstate improvement.


Additional Experience
=====================

PL011 provides a pattern to group all registers in one BqlRefCell
instead of multiple BqlCells.

I also tried to leverage this design to HPET, but it didn't fit very
well with this issue:
 * HPETState abstracts many helpers to check register bit and tell
   caller about the state, e.g., is_legacy_mode(),
   is_timer_int_active(), etc.
   
   But this also means these helpers can't be used in BqlRefCell::
   borrow_mut() context again, otherwise, they would cause the runtime
   bql check panic.

 - Some cases are easy to fix, i.e, use borrow_mut to modify the
   registers after the helpers' call.

 - Some cases would by tricky, like memory write callback, since it has
   complex logic and it's hard to decouple register changes from the
   reset logic as clearly as PL011 does. 

   The fix for this case is either to avoid using register helpers
   again in the borrow_mut context of write(), or to use BqlCell
   instead of BqlRefCell to get finer-grained access control to avoid
   refactoring code logic.

   I chose the latter.


So I think this might be a practical lesson that the choice of BqlCell
and BqlRefCell is also indeed related to code logic: If the code logic
is too complex to decouple borrow() and borrow_mut() (and the compiler
doesn't check this, only the runtime's panic_already_borrowed() will
complains!) , then BqlCell should be chosen. Because fine-grained access
is easier to control and avoid errors. :-)

[1]: https://lore.kernel.org/qemu-devel/20241205060714.256270-1-zhao1.liu@intel.com/
[2]: https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/software-developers-hpet-spec-1-0a.pdf

Thanks and Best Rgards,
Zhao
---
Zhao Liu (10):
  i386/fw_cfg: move hpet_cfg definition to hpet.c
  rust/qdev: add the macro to define bit property
  rust/irq: Add a helper to convert [InterruptSource] to [*mut IRQState]
  rust: add bindings for gpio_{in|out} initialization
  rust: add bindings for memattrs
  rust: add bindings for timer
  rust/timer/hpet: define hpet_cfg
  rust/timer/hpet: add basic HPET timer and HPETState
  rust/timer/hpet: add qom and qdev APIs support
  i386: enable rust hpet for pc when rust is enabled

 configs/devices/i386-softmmu/default.mak |   1 +
 hw/i386/fw_cfg.c                         |   6 +-
 hw/i386/pc.c                             |   2 +-
 hw/timer/Kconfig                         |   6 +-
 hw/timer/hpet.c                          |  14 +-
 include/hw/timer/hpet.h                  |   2 +-
 meson.build                              |   7 +
 rust/Cargo.lock                          |   8 +
 rust/Cargo.toml                          |   1 +
 rust/hw/Kconfig                          |   1 +
 rust/hw/meson.build                      |   1 +
 rust/hw/timer/Kconfig                    |   2 +
 rust/hw/timer/hpet/Cargo.toml            |  14 +
 rust/hw/timer/hpet/meson.build           |  18 +
 rust/hw/timer/hpet/src/fw_cfg.rs         |  85 +++
 rust/hw/timer/hpet/src/hpet.rs           | 900 +++++++++++++++++++++++
 rust/hw/timer/hpet/src/lib.rs            |  18 +
 rust/hw/timer/meson.build                |   1 +
 rust/qemu-api/meson.build                |   1 +
 rust/qemu-api/src/irq.rs                 |  18 +-
 rust/qemu-api/src/lib.rs                 |   1 +
 rust/qemu-api/src/memory.rs              |  16 +-
 rust/qemu-api/src/qdev.rs                |  49 +-
 rust/qemu-api/src/timer.rs               |  92 +++
 rust/qemu-api/src/zeroable.rs            |   7 +-
 rust/wrapper.h                           |   3 +
 tests/qtest/meson.build                  |   3 +-
 27 files changed, 1252 insertions(+), 25 deletions(-)
 create mode 100644 rust/hw/timer/Kconfig
 create mode 100644 rust/hw/timer/hpet/Cargo.toml
 create mode 100644 rust/hw/timer/hpet/meson.build
 create mode 100644 rust/hw/timer/hpet/src/fw_cfg.rs
 create mode 100644 rust/hw/timer/hpet/src/hpet.rs
 create mode 100644 rust/hw/timer/hpet/src/lib.rs
 create mode 100644 rust/hw/timer/meson.build
 create mode 100644 rust/qemu-api/src/timer.rs

-- 
2.34.1



^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2025-02-08 17:52 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-25 12:51 [PATCH 00/10] rust: Add HPET timer device Zhao Liu
2025-01-25 12:51 ` [PATCH 01/10] i386/fw_cfg: move hpet_cfg definition to hpet.c Zhao Liu
2025-01-25 12:51 ` [PATCH 02/10] rust/qdev: add the macro to define bit property Zhao Liu
2025-01-25 12:51 ` [PATCH 03/10] rust/irq: Add a helper to convert [InterruptSource] to [*mut IRQState] Zhao Liu
2025-01-29 10:51   ` Paolo Bonzini
2025-02-07  7:10     ` Zhao Liu
2025-02-07  7:44       ` Zhao Liu
2025-02-07  9:57         ` Paolo Bonzini
2025-02-08 11:14           ` Zhao Liu
2025-02-08 11:39             ` Paolo Bonzini
2025-02-08 18:10               ` Zhao Liu
2025-01-25 12:51 ` [PATCH 04/10] rust: add bindings for gpio_{in|out} initialization Zhao Liu
2025-01-29 10:59   ` Paolo Bonzini
2025-02-07  8:43     ` Zhao Liu
2025-02-07  9:54       ` Paolo Bonzini
2025-02-08 11:16         ` Zhao Liu
2025-01-25 12:51 ` [PATCH 05/10] rust: add bindings for memattrs Zhao Liu
2025-01-25 12:51 ` [PATCH 06/10] rust: add bindings for timer Zhao Liu
2025-01-29 10:58   ` Paolo Bonzini
2025-02-07 13:33     ` Zhao Liu
2025-02-07 14:55       ` Paolo Bonzini
2025-02-08 11:08         ` Zhao Liu
2025-01-25 12:51 ` [PATCH 07/10] rust/timer/hpet: define hpet_cfg Zhao Liu
2025-01-29 10:58   ` Paolo Bonzini
2025-02-07 14:30     ` Zhao Liu
2025-01-25 12:51 ` [PATCH 08/10] rust/timer/hpet: add basic HPET timer and HPETState Zhao Liu
2025-01-29 10:57   ` Paolo Bonzini
2025-02-08  8:19     ` Zhao Liu
2025-01-25 12:51 ` [PATCH 09/10] rust/timer/hpet: add qom and qdev APIs support Zhao Liu
2025-01-29 10:58   ` Paolo Bonzini
2025-02-08 10:55     ` Zhao Liu
2025-02-08 11:41       ` Paolo Bonzini
2025-02-08 18:06         ` Zhao Liu
2025-01-25 12:51 ` [PATCH 10/10] i386: enable rust hpet for pc when rust is enabled Zhao Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).