Age | Commit message (Collapse) | Author | Files | Lines |
|
It's valid for the caller to pass a NULL chardev to pl011_create();
this means "don't set the chardev property on the device", which
in turn means "act like there's no chardev". All the chardev
frontend APIs (in C, at least) accept a NULL pointer to mean
"do nothing".
This fixes some failures in 'make check-functional' when Rust support
is enabled.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Link: https://lore.kernel.org/r/20250307190051.3274226-1-peter.maydell@linaro.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Generalize timer_and_addr() to decode all registers into a single enum
HPETRegister, and use the TryInto derive to separate valid and
invalid values.
The main advantage lies in checking that all registers are enumerated
in the "match" statements.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
The values stored in the Fifo are instances of the bitfield-struct
registers::Data. Convert as soon as possible the value written
into DR, and always refer to the bitfield struct; it's generally
cleaner other than PL011State::receive having to do a double
conversion u8=>u32=>registers::Data.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Switch bindings::CharBackend with chardev::CharBackend. This removes
occurrences of "unsafe" due to FFI and switches the wrappers for receive,
can_receive and event callbacks to the common ones implemented by
chardev::CharBackend.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Do not make callbacks unnecessarily "pub", they are only used
through function pointers.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Fields of SysBusDevice must only be accessed with the BQL taken. Add
a wrapper that verifies that.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Timers must be pinned in memory, because modify() stores a pointer to them
in the TimerList. To express this requirement, change init_full() to take
a pinned reference. Because the only way to obtain a Timer is through
Timer::new(), which is unsafe, modify() can assume that the timer it got
was later initialized; and because the initialization takes a Pin<&mut
Timer> modify() can assume that the timer is pinned. In the future the
pinning requirement will be expressed through the pin_init crate instead.
Note that Timer is a bit different from other users of Opaque, in that
it is created in Rust code rather than C code. This is why it has to
use the unsafe constructors provided by Opaque; and in fact Timer::new()
is also unsafe, because it leaves it to the caller to invoke init_full()
before modify(). Without a call to init_full(), modify() will cause a
NULL pointer dereference.
An alternative could be to combine new() + init_full() by returning a
pinned box; however, using a reference makes it easier to express
the requirement that the opaque outlives the timer.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
This simplifies things for migration, since Option<Box<QEMUTimer>> does not
implement VMState.
This also shows a soundness issue because Timer::new() will leave a NULL
timer list pointer, which can then be dereferenced by Timer::modify(). It
will be fixed shortly.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
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>
|
|
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>
|
|
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>
|
|
Tell clippy the minimum supported Rust version for QEMU.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
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>
|
|
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>
|
|
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>
|
|
read() can now return a simple u64.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Prepare for moving all references to the registers and the FIFO into a
separate struct.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
As an added bonus, this also makes the new function return u32 instead
of u64, thus factoring some casts into a single place.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
The only public interfaces for pl011 are TYPE_PL011 and pl011_create.
Remove pub from everything else.
Note: the "allow(dead_code)" is removed later.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Do not use new_unchecked; the effect is the same, but the
code is easier to read and unsafe regions become smaller.
Likewise, NonNull::new can be used instead of assertion and
followed by as_ref() or as_mut() instead of dereferencing the
pointer.
Suggested-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Place struct_name before field_name, similar to offset_of.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
List all the necessary bindings to better identify gaps in rust/qapi.
And include the bindings wrapped by rust/qapi instead mapping the raw
bindings directly.
Inspired-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20250121140457.84631-3-zhao1.liu@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
A safe REALIZE accepts immutable reference.
Since current PL011's realize() only calls a char binding function (
qemu_chr_fe_set_handlers), it is possible to convert mutable reference
(&mut self) to immutable reference (&self), which only needs to convert
the pointers passed to C to mutable pointers.
Thus, make REALIZE accept immutable reference.
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20250121140457.84631-2-zhao1.liu@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
The ObjectDeref trait now provides all the magic that is required to fake
inheritance. Replace the "impl SysBusDevice" block of qemu_api::sysbus
with a trait, so that sysbus_init_irq() can be invoked as "self.init_irq()"
without any intermediate upcast.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
This is going to be fairly common. Using a custom procedural macro
provides better error messages and automatically finds the right
type.
Note that this is different from the same-named macro in the
derive_more crate. That one provides conversion from e.g. tuples
to enums with tuple variants, not from integers to enums.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Leave IRQ and MMIO initialization to instance_post_init. In Rust the
two callbacks are more distinct, because only instance_post_init has a
fully initialized object available.
While at it, add a wrapper for sysbus_init_mmio so that accesses to
the SysBusDevice correctly use shared references.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
There is no need to monkeypatch DeviceId::Luminary into the already-initialized
PL011State. Instead, now that we can define a class hierarchy, we can define
PL011Class and make device_id a field in there.
There is also no need anymore to have "Arm" as zero, so change DeviceId into a
wrapper for the array; all it does is provide an Index<hwaddr> implementation
because arrays can only be indexed by usize.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|