aboutsummaryrefslogtreecommitdiff
path: root/rust
AgeCommit message (Collapse)AuthorFilesLines
2025-03-06rust: qemu_api_macros: add Wrapper derive macroPaolo Bonzini3-6/+136
Add a derive macro that makes it easy to peel off all the layers of specialness (UnsafeCell, MaybeUninit, etc.) and just get a pointer to the wrapped type; and likewise add them back starting from a *mut. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: cell: add wrapper for FFI typesPaolo Bonzini1-7/+197
Inspired by the same-named type in Linux. This type provides the compiler with a correct view of what goes on with FFI types. In addition, it separates the glue code from the bindgen-generated code, allowing traits such as Send, Sync or Zeroable to be specified independently for C and Rust structs. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: qom: get rid of ClassInitImplPaolo Bonzini6-130/+101
Complete the conversion from the ClassInitImpl trait to class_init() methods. This will provide more freedom to split the qemu_api crate in separate parts. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: pl011, qemu_api tests: do not use ClassInitImplPaolo Bonzini2-40/+31
Outside the qemu_api crate, orphan rules make the usage of ClassInitImpl unwieldy. Now that it is optional, do not use it. For PL011Class, this makes it easier to provide a PL011Impl trait similar to the ones in the qemu_api crate. The device id consts are moved there. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: qom: add ObjectImpl::CLASS_INITPaolo Bonzini4-4/+19
As shown in the PL011 device, the orphan rules required a manual implementation of ClassInitImpl for anything not in the qemu_api crate; this gets in the way of moving system emulation-specific code (including DeviceClass, which as a blanket ClassInitImpl<DeviceClass> implementation) into its own crate. Make ClassInitImpl optional, at the cost of having to specify the CLASS_INIT member by hand in every implementation of ObjectImpl. The next commits will get rid of it, replacing all the "impl<T> ClassInitImpl<Class> for T" blocks with a generic class_init<T> method on Class. Right now the definition is always the same, but do not provide a default as that will not be true once ClassInitImpl goes away. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: add SysBusDeviceImplPaolo Bonzini3-5/+12
The only function, right now, is to ensure that anything with a SysBusDeviceClass class is a SysBusDevice. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: add IsA bounds to QOM implementation traitsPaolo Bonzini2-2/+4
Check that the right bounds are provided to the qom_isa! macro whenever the class is defined to implement a certain class. This removes the need to add IsA<> bounds together with the *Impl trait bounds. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: prefer importing std::ptr over core::ptrZhao Liu3-5/+6
The std::ptr is same as core::ptr, but std has already been used in many cases and there's no need to choose non-std library. So, use std::ptr directly to make the used ptr library as consistent as possible. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250218080835.3341082-1-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: tests: do not import bindings::*Paolo Bonzini1-1/+2
Similar to the devices, spell the exact set of C functions that are called directly. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: add module to convert between success/-errno and io::ResultPaolo Bonzini5-0/+380
It is a common convention in QEMU to return a positive value in case of success, and a negated errno value in case of error. Unfortunately, using errno portably in Rust is a bit complicated; on Unix the errno values are supported natively by io::Error, but on Windows they are not; so, use the libc crate. This is a set of utility functions that are used by both chardev and block layer bindings. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25rust: subprojects: add libc cratePaolo Bonzini2-0/+8
This allows access to errno values. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-25i386: Fix the missing Rust HPET configuration optionZhao Liu1-0/+1
The configuration option of Rust HPET is missing, so that PC machine can't boot with "hpet=on" when QEMU Rust support is enabled. Add the Rust HPET configuration option. Fixes: d128c341a744 ("i386: enable rust hpet for pc when rust is enabled") Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250217154416.3144571-1-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: fix doctestsPaolo Bonzini2-2/+2
Doctests were not being run by CI, and have broken. Fix them. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: vmstate: remove redundant link targetsPaolo Bonzini1-3/+2
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qemu_api: add a documentation header for all modulesPaolo Bonzini7-0/+27
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13i386: enable rust hpet for pc when rust is enabledZhao Liu2-0/+3
Add HPET configuration in PC's Kconfig options, and select HPET device (Rust version) if Rust is supported. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-11-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust/timer/hpet: add qom and qdev APIs supportZhao Liu3-11/+273
Implement QOM & QAPI support for HPET device. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-10-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust/timer/hpet: add basic HPET timer and HPETStateZhao Liu3-0/+631
Add the HPETTimer and HPETState (HPET timer block), along with their basic methods and register definitions. This is in preparation for supporting the QAPI interfaces. Note, wrap all items in HPETState that may be changed in the callback called by C code into the BqlCell/BqlRefCell. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-9-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust/timer/hpet: define hpet_fw_cfgZhao Liu9-2/+132
Define HPETFwEntry structure with the same memory layout as hpet_fw_entry in C. Further, define the global hpet_cfg variable in Rust which is the same as the C version. This hpet_cfg variable in Rust will replace the C version one and allows both Rust code and C code to access it. The Rust version of hpet_cfg is self-contained, avoiding unsafe access to C code. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-8-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: add bindings for timerZhao Liu4-0/+101
Add timer bindings to help handle idiomatic Rust callbacks. Additionally, wrap QEMUClockType in ClockType binding to avoid unsafe calls in device code. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-7-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: add bindings for memattrsZhao Liu3-2/+16
The MemTxAttrs structure contains bitfield members, and bindgen is unable to generate an equivalent macro definition for MEMTXATTRS_UNSPECIFIED. Therefore, manually define a global constant variable MEMTXATTRS_UNSPECIFIED to support calls from Rust code. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250125125137.1223277-6-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: add bindings for gpio_{in|out} initializationZhao Liu2-5/+43
Wrap qdev_init_gpio_{in|out} as methods in DeviceMethods. And for qdev_init_gpio_in, based on FnCall, it can support idiomatic Rust callback without the need for C style wrapper. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-5-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust/irq: Add a helper to convert [InterruptSource] to pointerZhao Liu1-0/+6
This is useful when taking an InterruptSource slice and passing it to C function. Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-4-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust/qdev: add the macro to define bit propertyZhao Liu1-0/+12
HPET device (Rust device) needs to define the bit type property. Add a variant of define_property macro to define bit type property. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250210030051.2562726-3-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: pl011: convert pl011_create to safe RustPaolo Bonzini2-24/+51
Not a major change but, as a small but significant step in creating qdev bindings, show how pl011_create can be written without "unsafe" calls (apart from converting pointers to references). This also provides a starting point for creating Error** bindings. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: chardev, qdev: add bindings to qdev_prop_set_chrPaolo Bonzini5-1/+32
Because the argument to the function is an Owned<Chardev>, this also adds an ObjectType implementation to Chardev. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: irq: define ObjectType for IRQStatePaolo Bonzini1-3/+12
This is a small preparation in order to use an Owned<IRQState> for the argument to sysbus_connect_irq. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: bindings for MemoryRegionOpsPaolo Bonzini8-61/+226
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: bindings: add Send and Sync markers for types that have bindingsPaolo Bonzini2-0/+49
This is needed for the MemoryRegionOps<T> to be declared as static; Rust requires static elements to be Sync. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qdev: switch from legacy reset to ResettablePaolo Bonzini3-28/+98
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qdev: make ObjectImpl a supertrait of DeviceImplPaolo Bonzini1-2/+2
In practice it has to be implemented always in order to access an implementation of ClassInitImpl<ObjectClass>. Make the relationship explicit in the code. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qom: allow initializing interface vtablesPaolo Bonzini2-2/+44
Unlike regular classes, interface vtables can only be obtained via object_class_dynamic_cast. Provide a wrapper that allows accessing the vtable and pass it to a ClassInitImpl implementation, for example ClassInitImpl<ResettableClass>. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qdev: add clock creationPaolo Bonzini4-31/+125
Add a Rust version of qdev_init_clock_in, which can be used in instance_init. There are a couple differences with the C version: - in Rust the object keeps its own reference to the clock (in addition to the one embedded in the NamedClockList), and the reference is dropped automatically by instance_finalize(); this is encoded in the signature of DeviceClassMethods::init_clock_in, which makes the lifetime of the clock independent of that of the object it holds. This goes unnoticed in the C version and is due to the existence of aliases. - also, anything that happens during instance_init uses the pinned_init framework to operate on a partially initialized object, and is done through class methods (i.e. through DeviceClassMethods rather than DeviceMethods) because the device does not exist yet. Therefore, Rust code *must* create clocks from instance_init, which is stricter than C. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: callbacks: allow passing optional callbacks as ()Paolo Bonzini1-0/+97
In some cases, callbacks are optional. Using "Some(function)" and "None" does not work well, because when someone writes "None" the compiler does not know what to use for "F" in "Option<F>". Therefore, adopt () to mean a "null" callback. It is possible to enforce that a callback is valid by adding a "let _: () = F::ASSERT_IS_SOME" before the invocation of F::call. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qom: add object creation functionalityPaolo Bonzini4-34/+48
The basic object lifecycle test can now be implemented using safe code! Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qom: add reference counting functionalityPaolo Bonzini3-7/+178
Add a smart pointer that allows to add and remove references from QOM objects. It's important to note that while all QOM objects have a reference count, in practice not all of them have their lifetime guarded by it. Embedded objects, specifically, are confined to the lifetime of the owner. When writing Rust bindings this is important, because embedded objects are *never* used through the "Owned<>" smart pointer that is introduced here. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-10rust: restrict missing_const_for_fn to qemu_api cratePaolo Bonzini2-1/+1
missing_const_for_fn is not necessarily useful or good. For example in a private API you can always add const later, and in a public API it can be unnecessarily restrictive to annotate everything with const (blocking further improvements to the API). Nevertheless, QEMU turns it on because qemu_api uses const quite aggressively and therefore it can be handy to have as much as possible annotated with const. Outside qemu_api though, not so much: devices are self contained consumers and if there is nothing that could use their functions in const contexts that were not anticipated. Since missing_const_for_fn can be a bit noisy and trigger on trivial functions that no one would ever call in const context, do not turn it on everywhere and only keep it in qemu_api as a special case. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-07rust: pl011: use default set of lintsPaolo Bonzini1-9/+0
Being the first crate added to QEMU, pl011 has a rather restrictive Clippy setup. This can be sometimes a bit too heavy on its suggestions, for example error: this could be a `const fn` --> hw/char/pl011/src/device.rs:382:5 | 382 | / fn set_read_trigger(&mut self) { 383 | | self.read_trigger = 1; 384 | | } | |_____^ Just use the standard set that is present in rust/Cargo.toml, with just a small adjustment to allow upper case acronyms which are used for register names. Reported-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-07rust: add clippy configuration filePaolo Bonzini1-0/+2
Configure the minimum supported Rust version (though strictly speaking that's redundant with Cargo.toml), and the list of CamelCase identifiers that are not Rust types. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-07rust: include rust_version in Cargo.tomlPaolo Bonzini4-1/+3
Tell clippy the minimum supported Rust version for QEMU. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-07rust: remove unnecessary Cargo.toml metadataPaolo Bonzini5-46/+6
Some items of Cargo.toml (readme, homepage, repository) are only present because of clippy::cargo warnings being enabled in rust/hw/char/pl011/src/lib.rs. But these items are not particularly useful and would be all the same for all Cargo.toml files in the QEMU workspace. Clean them up. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-28rust: qemu-api: add sub-subclass to the integration testsZhao Liu1-3/+53
Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-28rust/zeroable: Implement Zeroable with const_zero macroZhao Liu1-76/+61
The `const_zero` crate provides a nice macro to zero type-specific constants, which doesn't need to enumerates the fields one by one. Introduce the `const_zero` macro to QEMU (along with its documentation), and use it to simplify the implementation of `Zeroable` trait. Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250123163143.679841-1-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-28rust: qdev: make reset take a shared referencePaolo Bonzini2-3/+3
Because register reset is within a borrow_mut() call, reset does not need anymore a mut reference to the PL011State. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-28rust: pl011: drop use of ControlFlowPaolo Bonzini1-21/+18
It is a poor match for what the code is doing, anyway. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-28rust: pl011: pull device-specific code out of MemoryRegionOps callbacksPaolo Bonzini2-26/+15
read() can now return a simple u64. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-28rust: pl011: remove duplicate definitionsPaolo Bonzini2-49/+29
Unify the "Interrupt" enum and the "INT_*" constants with a struct that contains the bits. The "int_level" and "int_enabled" fields could use a crate such as "bitflags". Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-28rust: pl011: wrap registers with BqlRefCellPaolo Bonzini2-22/+32
This is a step towards making memory ops use a shared reference to the device type; it's not yet possible due to the calls to character device functions. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-27rust: pl011: extract PL011RegistersPaolo Bonzini2-127/+166
Pull all the mutable fields of PL011State into a separate struct. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-27rust: pl011: pull interrupt updates out of read/write opsPaolo Bonzini1-36/+48
qemu_irqs are not part of the vmstate, therefore they will remain in PL011State. Update them if needed after regs_read()/regs_write(). Apply #[must_use] to functions that return whether the interrupt state could have changed, so that it's harder to forget the call to update(). Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>