From nobody Sun Dec 14 02:01:12 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1747815595; cv=none; d=zohomail.com; s=zohoarc; b=SmBDfgj5455aIKgjsrA0JzD2rlbpj+GbMI5htCg5Nr3xZ53piaEQiR0+rGONAZ9bVfxTgaUOzklgGftnZStYwBAE41FwtN4y2CydnJtfQKewkBReRgFAQsDknTv2Zy8+fpC9V5lYdX1KqvDUEsHRrFLV1w0XQCdpKS5Ph+Yj+mo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747815595; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=XkexbcE3Ct1IaeE/EpP007cd4zT7zhozCvcoCpvD4Pg=; b=S5MxV1EiPVjpvYgrawBG12p7LYo0bz+1p7XxPc2ymd5HlhLsm7/8nra+VxeODYBIDuOBjHElr8MKz8klRntHvOFcN1fYftoLUgcg9TN6oV5aaGSLDmKVY5+Gd9HG17jlCrs+OH16BVLd+BdXjcBv/3tGWM8JHPpQuPUFP4LXLmk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747815595132202.03291174559092; Wed, 21 May 2025 01:19:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHefQ-0004pl-9W; Wed, 21 May 2025 04:19:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHefI-0004n9-Ti for qemu-devel@nongnu.org; Wed, 21 May 2025 04:19:04 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHefA-0000AQ-UK for qemu-devel@nongnu.org; Wed, 21 May 2025 04:19:04 -0400 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-619-phUuMzNYPa65FUS0MKI7NQ-1; Wed, 21 May 2025 04:18:53 -0400 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-441c122fa56so31120065e9.2 for ; Wed, 21 May 2025 01:18:53 -0700 (PDT) Received: from [192.168.122.1] ([151.95.46.79]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3a362997dc8sm17276234f8f.46.2025.05.21.01.18.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 May 2025 01:18:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747815536; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XkexbcE3Ct1IaeE/EpP007cd4zT7zhozCvcoCpvD4Pg=; b=ajrgAU3rXuVv6QZIPExy002rtkYgfUE3sSNMvdUloSrJ/IT+C1XmkxJcGDKp8IV9LPSaA0 clmHz8zm6oaxOzn4VWYCgwILjGstwq3/E7jVrWB/8aGwv7/XvJptedFfcC9GgWsKWozbSh 1wAN07Hl+gQ/sJIZhSRjs+ZKAtKkhCI= X-MC-Unique: phUuMzNYPa65FUS0MKI7NQ-1 X-Mimecast-MFC-AGG-ID: phUuMzNYPa65FUS0MKI7NQ_1747815533 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747815532; x=1748420332; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XkexbcE3Ct1IaeE/EpP007cd4zT7zhozCvcoCpvD4Pg=; b=TPCxL4QbaxFUU4e0SY/K7AOdYcvSPzY0fLh4vX+LOXskiALUrMHmDrz4/sgLNY1EA3 Akrlbmai+Up9a4sf9KjDkziooIj3/dKN/oBPNBKzMIn/aZuHXZE5eyvRTOsgjhyEQSXT IyXuLt4qFikMR+wVbJB7UU+0bTpzNBRnfGqItgZ0iCTKhrLR5UBQiFjwYgeIZ17ZwY6P vxGu+mGCgNi6074I7hCkD0AFo4iyKWKIhlsbI2spOZFOCcgzYDFRN9r5DofqCVrj7zIZ 4RqXkwjX3ltD2MkM6PQBop9f8vBSVIhVFGW1G6nvC1HJBNKLKGu2tnQBOYAAMJfzc4Qn oF7A== X-Gm-Message-State: AOJu0YwsEAxYO36fUCR1W+7QtIAo5jYcRmVqohP234IV5mWgbnVZzIx/ FHNQ2rhHQXjMbyePhnWIjKEpwLqt8pISACSDMc++1hvy/Lank+UlqS6Kzf8Pi5oglD8q82g/sg1 wJRUp28WV4VEjHfBvHAWBqZm9KqQEnb8Jigge4P1K9h5lKVSreOlmN19xp/QYwQmWnxDUvcGGH9 EnFZpxDCMqwjKVVEVZBQE8YqSe6FqGsp9fm4qnVb74 X-Gm-Gg: ASbGncu7NwmURWPpuKecWfZ53ampGbgKI3+fkDWB4+qLlD4yqKOmc5mGE+SgUiRl1IH P634oFXAvp6Ui1WuohUqYqa9PoGbZPoRhJXKadnS9z5If34ZSei7pR9M8FtXmTA7pgWuxwAG1sv JXY4Hcxgel7bfQz0eRCmyy11hMsAcKjjMjNnepb4Kbez/+GpqftaYbvxzskxYMt6LguESLUZgMj Vz1oKzib/ExT1ysWCtMjB8O4krQTPTSysLdllKN1h6OnaieQ9yVKtW5NzakbfoQ+VYvoIxAp93n pYMhw+9HPlrZ/A== X-Received: by 2002:a05:600c:3114:b0:442:d9f2:ded8 with SMTP id 5b1f17b1804b1-442fd6444c4mr214127605e9.15.1747815531489; Wed, 21 May 2025 01:18:51 -0700 (PDT) X-Google-Smtp-Source: AGHT+IG/6nUcZiSuErZZc0W8D31IsWShGhVm8gljvv4BgZ09FIQ2PpzOCUXmO6iBT4qu92wcz3A2WA== X-Received: by 2002:a05:600c:3114:b0:442:d9f2:ded8 with SMTP id 5b1f17b1804b1-442fd6444c4mr214127045e9.15.1747815530838; Wed, 21 May 2025 01:18:50 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, qemu-rust@nongnu.org, manos.pitsidianakis@linaro.org Subject: [RFC PATCH 1/6] rust: add "bits", a custom bitflags implementation Date: Wed, 21 May 2025 10:18:40 +0200 Message-ID: <20250521081845.496442-2-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250521081845.496442-1-pbonzini@redhat.com> References: <20250521081845.496442-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.487, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1747815597467116600 Content-Type: text/plain; charset="utf-8" One common thing that device emulation does is manipulate bitmasks, for exa= mple to check whether two bitmaps have common bits. One example in the pl011 cr= ate is the checks for pending interrupts, where an interrupt cause corresponds = to at least one interrupt source from a fixed set. Unfortunately, this is one case where Rust *can* provide some kind of abstraction but it does so with a rather Perl-ish There Is More Way To Do It. It is not something where a crate like "bilge" helps, because it only covers the packing of bits in a structure; operations like "are all bits of Y set in X" almost never make sense for bit-packed structs; you need something else, there are several crates that do it and of course we're going to roll our own. In particular I examined three: - bitmask (https://docs.rs/bitmask/0.5.0/bitmask/) does not support const at all. This is a showstopper because one of the ugly things in the current pl011 code is the ugliness of code that defines interrupt masks at compile time: pub const E: Self =3D Self(Self::OE.0 | Self::BE.0 | Self::PE.0 | Self:= :FE.0); or even worse: const IRQMASK: [u32; 6] =3D [ Interrupt::E.0 | Interrupt::MS.0 | Interrupt::RT.0 | Interrupt::TX.0 = | Interrupt::RX.0, ... } You would have to use roughly the same code---"bitmask" only helps with defining the struct. - bitmask_enum (https://docs.rs/bitmask-enum/2.2.5/bitmask_enum/) does not have a good separation of "valid" and "invalid" bits, so for example "!x" will invert all 16 bits if you choose u16 as the representation -- even if you only defined 10 bits. This makes it easier to introduce subtle bugs in comparisons. - bitflags (https://docs.rs/bitflags/2.6.0/bitflags/) is generally the most used such crate and is the one that I took most inspiration from with respect to the syntax. It's a pretty sophisticated implementation, with a lot of bells and whistles such as an implementation of "Iter" that returns the bits one at a time. The main thing that all of them lack, however, is a way to simplify the ugly definitions like the above. "bitflags" includes const methods that perform AND/OR/XOR of masks (these are necessary because Rust operator overloading does not support const yet, and therefore overloaded operators cannot be used in the definition of a "static" variable), but they become even more verbose and unmanageable, like Interrupt::E.union(Interrupt::MS).union(Interrupt::RT).union(Interrupt::T= X).union(Interrupt::RX) This was the main reason to create "bits", which allows something like bits!(Interrupt: E | MS | RT | TX | RX) and expands it 1) add "Interrupt::" in front of all identifiers 2) convert operators to the wordy const functions like "union". It supports boolean operators "&", "|", "^", "!" and parentheses, with a relatively simple recursive descent parser that's implemented in qemu_api_macros. Signed-off-by: Paolo Bonzini --- rust/Cargo.lock | 7 + rust/Cargo.toml | 1 + rust/bits/Cargo.toml | 19 ++ rust/bits/meson.build | 12 + rust/bits/src/lib.rs | 441 +++++++++++++++++++++++++++++++ rust/meson.build | 1 + rust/qemu-api-macros/src/bits.rs | 227 ++++++++++++++++ rust/qemu-api-macros/src/lib.rs | 12 + 8 files changed, 720 insertions(+) create mode 100644 rust/bits/Cargo.toml create mode 100644 rust/bits/meson.build create mode 100644 rust/bits/src/lib.rs create mode 100644 rust/qemu-api-macros/src/bits.rs diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 13d580c693b..0dfe0fb6ced 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -31,6 +31,13 @@ dependencies =3D [ "syn", ] =20 +[[package]] +name =3D "bits" +version =3D "0.1.0" +dependencies =3D [ + "qemu_api_macros", +] + [[package]] name =3D "either" version =3D "1.12.0" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index d9faeecb10b..165328b6d01 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver =3D "2" members =3D [ + "bits", "qemu-api-macros", "qemu-api", "hw/char/pl011", diff --git a/rust/bits/Cargo.toml b/rust/bits/Cargo.toml new file mode 100644 index 00000000000..1ff38a41175 --- /dev/null +++ b/rust/bits/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name =3D "bits" +version =3D "0.1.0" +authors =3D ["Paolo Bonzini "] +description =3D "const-friendly bit flags" +resolver =3D "2" +publish =3D false + +edition.workspace =3D true +homepage.workspace =3D true +license.workspace =3D true +repository.workspace =3D true +rust-version.workspace =3D true + +[dependencies] +qemu_api_macros =3D { path =3D "../qemu-api-macros" } + +[lints] +workspace =3D true diff --git a/rust/bits/meson.build b/rust/bits/meson.build new file mode 100644 index 00000000000..2cd4121a546 --- /dev/null +++ b/rust/bits/meson.build @@ -0,0 +1,12 @@ +_bits_rs =3D static_library( + 'bits', + 'src/lib.rs', + override_options: ['rust_std=3D2021', 'build.rust_std=3D2021'], + rust_abi: 'rust', + dependencies: [qemu_api_macros], +) + +bits_rs =3D declare_dependency(link_with: _bits_rs) + +rust.test('rust-bits-tests', _bits_rs, + suite: ['unit', 'rust']) diff --git a/rust/bits/src/lib.rs b/rust/bits/src/lib.rs new file mode 100644 index 00000000000..d80a6263f1e --- /dev/null +++ b/rust/bits/src/lib.rs @@ -0,0 +1,441 @@ +/// # Definition entry point +/// +/// Define a struct with a single field of type $type. Include public con= stants +/// for each element listed in braces. +/// +/// The unnamed element at the end, if present, can be used to enlarge the= set +/// of valid bits. Bits that are valid but not listed are treated normall= y for +/// the purpose of arithmetic operations, and are printed with their hexad= ecimal +/// value. +/// +/// The struct implements the following traits: [`BitAnd`](std::ops::BitAn= d), +/// [`BitOr`](std::ops::BitOr), [`BitXor`](std::ops::BitXor), +/// [`Not`](std::ops::Not), [`Sub`](std::ops::Sub); [`Debug`](std::fmt::De= bug), +/// [`Display`](std::fmt::Display), [`Binary`](std::fmt::Binary), +/// [`Octal`](std::fmt::Octal), [`LowerHex`](std::fmt::LowerHex), +/// [`UpperHex`](std::fmt::UpperHex); [`From`]``/[`Into`]`` wh= ere +/// type is the type specified in the definition. +/// +/// ## Example +/// +/// ``` +/// # use bits::bits; +/// bits! { +/// pub struct Colors(u8) { +/// BLACK =3D 0, +/// RED =3D 1, +/// GREEN =3D 1 << 1, +/// BLUE =3D 1 << 2, +/// WHITE =3D (1 << 0) | (1 << 1) | (1 << 2), +/// } +/// } +/// ``` +/// +/// ``` +/// # use bits::bits; +/// # bits! { pub struct Colors(u8) { BLACK =3D 0, RED =3D 1, GREEN =3D 1 = << 1, BLUE =3D 1 << 2, } } +/// +/// bits! { +/// pub struct Colors8(u8) { +/// BLACK =3D 0, +/// RED =3D 1, +/// GREEN =3D 1 << 1, +/// BLUE =3D 1 << 2, +/// WHITE =3D (1 << 0) | (1 << 1) | (1 << 2), +/// +/// _ =3D 255, +/// } +/// } +/// +/// // The previously defined struct ignores bits not explicitly defined. +/// assert_eq!( +/// Colors::from(255).into_bits(), +/// (Colors::RED | Colors::GREEN | Colors::BLUE).into_bits() +/// ); +/// +/// // Adding "_ =3D 255" makes it retain other bits as well. +/// assert_eq!(Colors8::from(255).into_bits(), 255); +/// +/// // all() does not include the additional bits, valid_bits() does +/// assert_eq!(Colors8::all().into_bits(), Colors::all().into_bits()); +/// assert_eq!(Colors8::valid_bits().into_bits(), 255); +/// ``` +/// +/// # Evaluation entry point +/// +/// Return a constant corresponding to the boolean expression `$expr`. +/// Identifiers in the expression correspond to values defined for the +/// type `$type`. Supported operators are `!` (unary), `-`, `&`, `^`, `|`. +/// +/// ## Examples +/// +/// ``` +/// # use bits::bits; +/// bits! { +/// pub struct Colors(u8) { +/// BLACK =3D 0, +/// RED =3D 1, +/// GREEN =3D 1 << 1, +/// BLUE =3D 1 << 2, +/// // same as "WHITE =3D 7", +/// WHITE =3D bits!(Self as u8: RED | GREEN | BLUE), +/// } +/// } +/// +/// let rgb =3D bits! { Colors: RED | GREEN | BLUE }; +/// assert_eq!(rgb, Colors::WHITE); +/// ``` +#[macro_export] +macro_rules! bits { + { + $(#[$struct_meta:meta])* + $struct_vis:vis struct $struct_name:ident($field_vis:vis $type:ty)= { + $($(#[$const_meta:meta])* $const:ident =3D $val:expr),+ + $(,_ =3D $mask:expr)? + $(,)? + } + } =3D> { + $(#[$struct_meta])* + #[derive(Clone, Copy, PartialEq, Eq)] + #[repr(transparent)] + $struct_vis struct $struct_name($field_vis $type); + + impl $struct_name { + $( #[allow(dead_code)] $(#[$const_meta])* + pub const $const: $struct_name =3D $struct_name($val); )+ + + #[doc(hidden)] + const VALID__: $type =3D $( Self::$const.0 )|+ $(|$mask)?; + + #[allow(dead_code)] + #[inline(always)] + pub const fn empty() -> Self { + Self(0) + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn all() -> Self { + Self($( Self::$const.0 )|+) + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn valid_bits() -> Self { + Self(Self::VALID__) + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn valid(val: $type) -> bool { + (val & !Self::VALID__) =3D=3D 0 + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn any_set(self, mask: Self) -> bool { + (self.0 & mask.0) !=3D 0 + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn all_set(self, mask: Self) -> bool { + (self.0 & mask.0) =3D=3D mask.0 + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn none_set(self, mask: Self) -> bool { + (self.0 & mask.0) =3D=3D 0 + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn from_bits(value: $type) -> Self { + $struct_name(value) + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn into_bits(self) -> $type { + self.0 + } + + #[allow(dead_code)] + #[inline(always)] + pub fn set(&mut self, rhs: Self) { + self.0 |=3D rhs.0; + } + + #[allow(dead_code)] + #[inline(always)] + pub fn clear(&mut self, rhs: Self) { + self.0 &=3D !rhs.0; + } + + #[allow(dead_code)] + #[inline(always)] + pub fn toggle(&mut self, rhs: Self) { + self.0 ^=3D rhs.0; + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn intersection(self, rhs: Self) -> Self { + $struct_name(self.0 & rhs.0) + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn difference(self, rhs: Self) -> Self { + $struct_name(self.0 & !rhs.0) + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn symmetric_difference(self, rhs: Self) -> Self { + $struct_name(self.0 ^ rhs.0) + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn union(self, rhs: Self) -> Self { + $struct_name(self.0 | rhs.0) + } + + #[allow(dead_code)] + #[inline(always)] + pub const fn invert(self) -> Self { + $struct_name(self.0 ^ Self::VALID__) + } + } + + impl ::std::fmt::Binary for $struct_name { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt= ::Result { + // If no width, use the highest valid bit + let width =3D f.width().unwrap_or((Self::VALID__.ilog2() += 1) as usize); + write!(f, "{:0>width$.precision$b}", self.0, + width =3D width, + precision =3D f.precision().unwrap_or(width)) + } + } + + impl ::std::fmt::LowerHex for $struct_name { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt= ::Result { + <$type as ::std::fmt::LowerHex>::fmt(&self.0, f) + } + } + + impl ::std::fmt::Octal for $struct_name { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt= ::Result { + <$type as ::std::fmt::Octal>::fmt(&self.0, f) + } + } + + impl ::std::fmt::UpperHex for $struct_name { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt= ::Result { + <$type as ::std::fmt::UpperHex>::fmt(&self.0, f) + } + } + + impl ::std::fmt::Debug for $struct_name { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt= ::Result { + write!(f, "{}({})", stringify!($struct_name), self) + } + } + + impl ::std::fmt::Display for $struct_name { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt= ::Result { + use ::std::fmt::Display; + let mut first =3D true; + let mut left =3D self.0; + $(if Self::$const.0.is_power_of_two() && (self & Self::$co= nst).0 !=3D 0 { + if first { first =3D false } else { Display::fmt(&'|',= f)?; } + Display::fmt(stringify!($const), f)?; + left -=3D Self::$const.0; + })+ + if first { + Display::fmt(&'0', f) + } else if left !=3D 0 { + write!(f, "|{left:#x}") + } else { + Ok(()) + } + } + } + + impl ::std::cmp::PartialEq<$type> for $struct_name { + fn eq(&self, rhs: &$type) -> bool { + self.0 =3D=3D *rhs + } + } + + impl ::std::ops::BitAnd<$struct_name> for &$struct_name { + type Output =3D $struct_name; + fn bitand(self, rhs: $struct_name) -> Self::Output { + $struct_name(self.0 & rhs.0) + } + } + + impl ::std::ops::BitAndAssign<$struct_name> for $struct_name { + fn bitand_assign(&mut self, rhs: $struct_name) { + self.0 =3D self.0 & rhs.0 + } + } + + impl ::std::ops::BitXor<$struct_name> for &$struct_name { + type Output =3D $struct_name; + fn bitxor(self, rhs: $struct_name) -> Self::Output { + $struct_name(self.0 ^ rhs.0) + } + } + + impl ::std::ops::BitXorAssign<$struct_name> for $struct_name { + fn bitxor_assign(&mut self, rhs: $struct_name) { + self.0 =3D self.0 ^ rhs.0 + } + } + + impl ::std::ops::BitOr<$struct_name> for &$struct_name { + type Output =3D $struct_name; + fn bitor(self, rhs: $struct_name) -> Self::Output { + $struct_name(self.0 | rhs.0) + } + } + + impl ::std::ops::BitOrAssign<$struct_name> for $struct_name { + fn bitor_assign(&mut self, rhs: $struct_name) { + self.0 =3D self.0 | rhs.0 + } + } + + impl ::std::ops::Sub<$struct_name> for &$struct_name { + type Output =3D $struct_name; + fn sub(self, rhs: $struct_name) -> Self::Output { + $struct_name(self.0 & !rhs.0) + } + } + + impl ::std::ops::SubAssign<$struct_name> for $struct_name { + fn sub_assign(&mut self, rhs: $struct_name) { + self.0 =3D self.0 - rhs.0 + } + } + + impl ::std::ops::Not for &$struct_name { + type Output =3D $struct_name; + fn not(self) -> Self::Output { + $struct_name(self.0 ^ $struct_name::VALID__) + } + } + + impl ::std::ops::BitAnd<$struct_name> for $struct_name { + type Output =3D Self; + fn bitand(self, rhs: Self) -> Self::Output { + $struct_name(self.0 & rhs.0) + } + } + + impl ::std::ops::BitXor<$struct_name> for $struct_name { + type Output =3D Self; + fn bitxor(self, rhs: Self) -> Self::Output { + $struct_name(self.0 ^ rhs.0) + } + } + + impl ::std::ops::BitOr<$struct_name> for $struct_name { + type Output =3D Self; + fn bitor(self, rhs: Self) -> Self::Output { + $struct_name(self.0 | rhs.0) + } + } + + impl ::std::ops::Sub<$struct_name> for $struct_name { + type Output =3D Self; + fn sub(self, rhs: Self) -> Self::Output { + $struct_name(self.0 & !rhs.0) + } + } + + impl ::std::ops::Not for $struct_name { + type Output =3D Self; + fn not(self) -> Self::Output { + $struct_name(self.0 ^ Self::VALID__) + } + } + + impl From<$struct_name> for $type { + fn from(x: $struct_name) -> $type { + x.0 + } + } + + impl From<$type> for $struct_name { + fn from(x: $type) -> Self { + $struct_name(x & Self::VALID__) + } + } + }; + + { $type:ty: $expr:expr } =3D> { + ::qemu_api_macros::bits_const_internal! { $type @ ($expr) } + }; + + { $type:ty as $int_type:ty: $expr:expr } =3D> { + (::qemu_api_macros::bits_const_internal! { $type @ ($expr) }.into_= bits()) as $int_type + }; +} + +#[cfg(test)] +mod test { + bits! { + pub(crate) struct InterruptMask(u32) { + OE =3D 1 << 10, + BE =3D 1 << 9, + PE =3D 1 << 8, + FE =3D 1 << 7, + RT =3D 1 << 6, + TX =3D 1 << 5, + RX =3D 1 << 4, + DSR =3D 1 << 3, + DCD =3D 1 << 2, + CTS =3D 1 << 1, + RI =3D 1 << 0, + + E =3D bits!(Self as u32: OE | BE | PE | FE), + MS =3D bits!(Self as u32: RI | DSR | DCD | CTS), + } + } + + #[test] + pub fn test_not() { + assert_eq!( + !InterruptMask::from(InterruptMask::RT), + InterruptMask::E | InterruptMask::MS | InterruptMask::TX | Int= erruptMask::RX + ); + } + + #[test] + pub fn test_and() { + assert_eq!( + InterruptMask::from(0), + InterruptMask::MS & InterruptMask::OE + ) + } + + #[test] + pub fn test_or() { + assert_eq!( + InterruptMask::E, + InterruptMask::OE | InterruptMask::BE | InterruptMask::PE | In= terruptMask::FE + ); + } + + #[test] + pub fn test_xor() { + assert_eq!( + InterruptMask::E ^ InterruptMask::BE, + InterruptMask::OE | InterruptMask::PE | InterruptMask::FE + ); + } +} diff --git a/rust/meson.build b/rust/meson.build index 91e52b8fb8e..f370b0ec939 100644 --- a/rust/meson.build +++ b/rust/meson.build @@ -1,4 +1,5 @@ subdir('qemu-api-macros') +subdir('bits') subdir('qemu-api') =20 subdir('hw') diff --git a/rust/qemu-api-macros/src/bits.rs b/rust/qemu-api-macros/src/bi= ts.rs new file mode 100644 index 00000000000..b6e07d4e890 --- /dev/null +++ b/rust/qemu-api-macros/src/bits.rs @@ -0,0 +1,227 @@ +// shadowing is useful together with "if let" +#![allow(clippy::shadow_unrelated)] + +use proc_macro2::{ + Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree,= TokenTree as TT, +}; + +use crate::utils::MacroError; + +pub struct BitsConstInternal { + typ: TokenTree, +} + +fn paren(ts: TokenStream) -> TokenTree { + TT::Group(Group::new(Delimiter::Parenthesis, ts)) +} + +fn ident(s: &'static str) -> TokenTree { + TT::Ident(Ident::new(s, Span::call_site())) +} + +fn punct(ch: char) -> TokenTree { + TT::Punct(Punct::new(ch, Spacing::Alone)) +} + +/// Implements a recursive-descent parser that translates Boolean expressi= ons on +/// bitmasks to invocations of `const` functions defined by the `bits!` ma= cro. +impl BitsConstInternal { + // primary ::=3D '(' or ')' + // | ident + // | '!' ident + fn parse_primary( + &self, + tok: TokenTree, + it: &mut dyn Iterator, + out: &mut TokenStream, + ) -> Result, MacroError> { + let next =3D match tok { + TT::Group(ref g) =3D> { + if g.delimiter() !=3D Delimiter::Parenthesis && g.delimite= r() !=3D Delimiter::None { + return Err(MacroError::Message("expected parenthesis".= into(), g.span())); + } + let mut stream =3D g.stream().into_iter(); + let Some(first_tok) =3D stream.next() else { + return Err(MacroError::Message( + "expected operand, found ')'".into(), + g.span(), + )); + }; + let mut output =3D TokenStream::new(); + // start from the lowest precedence + let next =3D self.parse_or(first_tok, &mut stream, &mut ou= tput)?; + if let Some(tok) =3D next { + return Err(MacroError::Message( + format!("unexpected token {tok}"), + tok.span(), + )); + } + out.extend(Some(paren(output))); + it.next() + } + TT::Ident(_) =3D> { + let mut output =3D TokenStream::new(); + output.extend([ + self.typ.clone(), + TT::Punct(Punct::new(':', Spacing::Joint)), + TT::Punct(Punct::new(':', Spacing::Joint)), + tok, + ]); + out.extend(Some(paren(output))); + it.next() + } + TT::Punct(ref p) =3D> { + if p.as_char() !=3D '!' { + return Err(MacroError::Message("expected operand".into= (), p.span())); + } + let Some(rhs_tok) =3D it.next() else { + return Err(MacroError::Message( + "expected operand at end of input".into(), + p.span(), + )); + }; + let next =3D self.parse_primary(rhs_tok, it, out)?; + out.extend([punct('.'), ident("invert"), paren(TokenStream= ::new())]); + next + } + _ =3D> { + return Err(MacroError::Message("unexpected literal".into()= , tok.span())); + } + }; + Ok(next) + } + + fn parse_binop< + F: Fn( + &Self, + TokenTree, + &mut dyn Iterator, + &mut TokenStream, + ) -> Result, MacroError>, + >( + &self, + tok: TokenTree, + it: &mut dyn Iterator, + out: &mut TokenStream, + ch: char, + f: F, + method: &'static str, + ) -> Result, MacroError> { + let mut next =3D f(self, tok, it, out)?; + while next.is_some() { + let op =3D next.as_ref().unwrap(); + let TT::Punct(ref p) =3D op else { break }; + if p.as_char() !=3D ch { + break; + } + + let Some(rhs_tok) =3D it.next() else { + return Err(MacroError::Message( + "expected operand at end of input".into(), + p.span(), + )); + }; + let mut rhs =3D TokenStream::new(); + next =3D f(self, rhs_tok, it, &mut rhs)?; + out.extend([punct('.'), ident(method), paren(rhs)]); + } + Ok(next) + } + + // sub ::=3D primary ('-' primary)* + pub fn parse_sub( + &self, + tok: TokenTree, + it: &mut dyn Iterator, + out: &mut TokenStream, + ) -> Result, MacroError> { + self.parse_binop(tok, it, out, '-', Self::parse_primary, "differen= ce") + } + + // and ::=3D sub ('&' sub)* + fn parse_and( + &self, + tok: TokenTree, + it: &mut dyn Iterator, + out: &mut TokenStream, + ) -> Result, MacroError> { + self.parse_binop(tok, it, out, '&', Self::parse_sub, "intersection= ") + } + + // xor ::=3D and ('&' and)* + fn parse_xor( + &self, + tok: TokenTree, + it: &mut dyn Iterator, + out: &mut TokenStream, + ) -> Result, MacroError> { + self.parse_binop(tok, it, out, '^', Self::parse_and, "symmetric_di= fference") + } + + // or ::=3D xor ('|' xor)* + pub fn parse_or( + &self, + tok: TokenTree, + it: &mut dyn Iterator, + out: &mut TokenStream, + ) -> Result, MacroError> { + self.parse_binop(tok, it, out, '|', Self::parse_xor, "union") + } + + pub fn parse( + it: &mut dyn Iterator, + ) -> Result { + let mut pos =3D Span::call_site(); + let mut typ =3D proc_macro2::TokenStream::new(); + + // Gobble everything up to an `@` sign, which is followed by a + // parenthesized expression; that is, all token trees except the + // last two form the type. + let next =3D loop { + let tok =3D it.next(); + if let Some(ref t) =3D tok { + pos =3D t.span(); + } + match tok { + None =3D> break None, + Some(TT::Punct(ref p)) if p.as_char() =3D=3D '@' =3D> { + let tok =3D it.next(); + if let Some(ref t) =3D tok { + pos =3D t.span(); + } + break tok; + } + Some(x) =3D> typ.extend(Some(x)), + } + }; + + let Some(tok) =3D next else { + return Err(MacroError::Message( + "expected expression, do not call this macro directly".int= o(), + pos, + )); + }; + let TT::Group(ref _group) =3D tok else { + return Err(MacroError::Message( + "expected parenthesis, do not call this macro directly".in= to(), + tok.span(), + )); + }; + let mut out =3D TokenStream::new(); + let state =3D Self { + typ: TT::Group(Group::new(Delimiter::None, typ)), + }; + + let next =3D state.parse_primary(tok, it, &mut out)?; + + // A parenthesized expression is a single production of the gramma= r, + // so the input must have reached the last token. + if let Some(tok) =3D next { + return Err(MacroError::Message( + format!("unexpected token {tok}"), + tok.span(), + )); + } + Ok(out) + } +} diff --git a/rust/qemu-api-macros/src/lib.rs b/rust/qemu-api-macros/src/lib= .rs index f97449bb304..ceb79f09f97 100644 --- a/rust/qemu-api-macros/src/lib.rs +++ b/rust/qemu-api-macros/src/lib.rs @@ -12,6 +12,9 @@ mod utils; use utils::MacroError; =20 +mod bits; +use bits::BitsConstInternal; + fn get_fields<'a>( input: &'a DeriveInput, msg: &str, @@ -219,3 +222,12 @@ pub fn derive_tryinto(input: TokenStream) -> TokenStre= am { =20 TokenStream::from(expanded) } + +#[proc_macro] +pub fn bits_const_internal(ts: TokenStream) -> TokenStream { + let ts =3D proc_macro2::TokenStream::from(ts); + let mut it =3D ts.into_iter(); + + let expanded =3D BitsConstInternal::parse(&mut it).unwrap_or_else(Into= ::into); + TokenStream::from(expanded) +} --=20 2.49.0 From nobody Sun Dec 14 02:01:12 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1747815677; cv=none; d=zohomail.com; s=zohoarc; b=C/LaCxuIEVR4uEIJD/t/jnhk8ib9jq0gD416UuSwx4UlTjsjdGZMBd2SztMJnMMZIj+M4mnu5V+XAdtKGe/3qYPz+mWbNPHhG/4DuISSGVugm++nhTA+WI98ti8Ead3vblEcV6v7ObqGEJJuaj1lV2jajFUXTrRJSMcElIKGyeg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747815677; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=TvUeya4TNcUwgoPZj33+aR4D24x0qlLX7SAj8FdNXBQ=; b=oArBDcgSy3psq1uh/hPol9e2FNmA/xcDNad9egq+Ybh5ReZ2uyWJFqjXfcY1dRUMy1eobbHhvYcJdVKsQEk69FW7MioA6cgdEXcI1SDpm/HfFXBey7xEn7hhYk+L9ScZaFj9OVWZN3z3Z8YQSCCVuhBfkbRR9b7VpOcwcC1RrB0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747815677566432.86378201353045; Wed, 21 May 2025 01:21:17 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHefc-0004tj-M4; Wed, 21 May 2025 04:19:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHefO-0004p1-Tw for qemu-devel@nongnu.org; Wed, 21 May 2025 04:19:11 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHefC-0000AS-Dm for qemu-devel@nongnu.org; Wed, 21 May 2025 04:19:09 -0400 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-645-zRunBgQiNL2a_6eOQyLWyQ-1; Wed, 21 May 2025 04:18:54 -0400 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43d734da1a3so35327995e9.0 for ; Wed, 21 May 2025 01:18:54 -0700 (PDT) Received: from [192.168.122.1] ([151.95.46.79]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-447f73d4aa2sm61404105e9.21.2025.05.21.01.18.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 May 2025 01:18:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747815536; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TvUeya4TNcUwgoPZj33+aR4D24x0qlLX7SAj8FdNXBQ=; b=h4trkLZvP103MBA0cQlHW9HYthawaqwyaVHPAtT+dt2GfOKajPU2Ue/UVPjUUKYwmDZuCA OVD30TduBYD5NcuK0pUuAlZ/rxesnbQM9jrKYWud6BF1MPWLAzkFBIfVY79ByFytGWrC85 EEZ/8/JzV0HQYD3tlWSqiRDd+D5q2KY= X-MC-Unique: zRunBgQiNL2a_6eOQyLWyQ-1 X-Mimecast-MFC-AGG-ID: zRunBgQiNL2a_6eOQyLWyQ_1747815534 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747815533; x=1748420333; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TvUeya4TNcUwgoPZj33+aR4D24x0qlLX7SAj8FdNXBQ=; b=rCp9BYwsC8U/J0TlUD6rYvo1G+hn6uIeDAfBCLgwLZ4eK8mSHX3dWZXwysyOSaoo2R k6uhgb3jkShd7YME1Mz6Oza23hZyl9XDPuGRHc2WZ5lRRyBTn3iIlJFwn6Rz+3VkqdEY A97CxC5/ZpwZ+XkKnD4xyQZeBc+7U02sup1dbDeethLl3x3rAiz2oj/zVLvT/gMQw/oQ AgInjRcL0gS2ZcddqGsPRAmzzpNK/RFFatem0jle1jCX20F8VysElRJWvq4tKYVlYxHR /yarNYYJOeFJvLab9soxBRpAvIcM1b0Vh8LPPNXM7ffCGxxUjU6Cgy8OxTY2U8b47/Lz gFUQ== X-Gm-Message-State: AOJu0YweXr9jrTWNBz4B/OJVD8uVRsjPaEF4kqbOCgHRBb3nKSkUECBG 3YJJlr3iNtjqrO+sdWCBodJ4uNx1kPdfmLeh5F7uXaTE7SKQI2wAwZu19Wyh0h29R5kdK0rfZc9 xGW8AxW/YEaXb+twlf1QvslCDos/7uhRF/DgkWSfhrA9jEefllh382iD/DIpuaJ2YHmqBo41v5x 1tPt3ROLPrIf3QlakXWQmm5mGwPYVxzVNm88xWOI2B X-Gm-Gg: ASbGncsVHYln8xFkW7RcJQAYG0+eyhhnhfSG0SzhnMApjAGZyWa9p81hNARvZHSKkcs zsVrD1/eFlc3VlWZ+RR+NCRzpXYhwSxDsO5G+hsV/lR06qTk4D3kNcTwiRW+OKZ3hblOWOGhdUz 8XVjlYI23aEgyjPMmEppv9UccO6qRUbQXDVBRxq0a4VV95E5bQyPqgO4ovXTEwNY1ocZIwmYt24 k1MGVn7ha29WPO/TnJWmXNUTo7z0i1WVtO8uXluq6ruHCf1CCw1/XXlSXXuTQ8ZdiUeicSbXBHb 14iAdAjEu2HZyg== X-Received: by 2002:a05:600c:154b:b0:43d:fa58:8378 with SMTP id 5b1f17b1804b1-442ff03c7ebmr141772995e9.33.1747815532544; Wed, 21 May 2025 01:18:52 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGSr4pzBy1XX8sKmCUrnbGxilzDfjYAPy6Afug8+TDre3jOzHh8kifNTVey5Nhkjy82ilnouw== X-Received: by 2002:a05:600c:154b:b0:43d:fa58:8378 with SMTP id 5b1f17b1804b1-442ff03c7ebmr141772735e9.33.1747815532098; Wed, 21 May 2025 01:18:52 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, qemu-rust@nongnu.org, manos.pitsidianakis@linaro.org Subject: [RFC PATCH 2/6] rust: pl011: use the bits macro Date: Wed, 21 May 2025 10:18:41 +0200 Message-ID: <20250521081845.496442-3-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250521081845.496442-1-pbonzini@redhat.com> References: <20250521081845.496442-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.487, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1747815678542116600 Content-Type: text/plain; charset="utf-8" This avoids the repeated ".0" when using the Interrupt struct. Signed-off-by: Paolo Bonzini --- rust/Cargo.lock | 1 + rust/hw/char/pl011/Cargo.toml | 1 + rust/hw/char/pl011/meson.build | 1 + rust/hw/char/pl011/src/device.rs | 51 ++++++++++++++--------------- rust/hw/char/pl011/src/registers.rs | 39 ++++++++++++---------- 5 files changed, 49 insertions(+), 44 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 0dfe0fb6ced..bccfe855a70 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -73,6 +73,7 @@ version =3D "0.1.0" dependencies =3D [ "bilge", "bilge-impl", + "bits", "qemu_api", "qemu_api_macros", ] diff --git a/rust/hw/char/pl011/Cargo.toml b/rust/hw/char/pl011/Cargo.toml index a1f431ab4a3..003ef9613d4 100644 --- a/rust/hw/char/pl011/Cargo.toml +++ b/rust/hw/char/pl011/Cargo.toml @@ -18,6 +18,7 @@ crate-type =3D ["staticlib"] [dependencies] bilge =3D { version =3D "0.2.0" } bilge-impl =3D { version =3D "0.2.0" } +bits =3D { path =3D "../../../bits" } qemu_api =3D { path =3D "../../../qemu-api" } qemu_api_macros =3D { path =3D "../../../qemu-api-macros" } =20 diff --git a/rust/hw/char/pl011/meson.build b/rust/hw/char/pl011/meson.build index 547cca5a96f..f134a6cdc6b 100644 --- a/rust/hw/char/pl011/meson.build +++ b/rust/hw/char/pl011/meson.build @@ -12,6 +12,7 @@ _libpl011_rs =3D static_library( dependencies: [ bilge_dep, bilge_impl_dep, + bits_rs, qemu_api, qemu_api_macros, ], diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/devi= ce.rs index bde3be65c5b..8d89c2448dc 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -85,8 +85,8 @@ pub struct PL011Registers { #[doc(alias =3D "cr")] pub control: registers::Control, pub dmacr: u32, - pub int_enabled: u32, - pub int_level: u32, + pub int_enabled: Interrupt, + pub int_level: Interrupt, pub read_fifo: Fifo, pub ilpr: u32, pub ibrd: u32, @@ -199,9 +199,9 @@ pub(self) fn read(&mut self, offset: RegisterOffset) ->= (bool, u32) { LCR_H =3D> u32::from(self.line_control), CR =3D> u32::from(self.control), FLS =3D> self.ifl, - IMSC =3D> self.int_enabled, - RIS =3D> self.int_level, - MIS =3D> self.int_level & self.int_enabled, + IMSC =3D> u32::from(self.int_enabled), + RIS =3D> u32::from(self.int_level), + MIS =3D> u32::from(self.int_level & self.int_enabled), ICR =3D> { // "The UARTICR Register is the interrupt clear register a= nd is write-only" // Source: ARM DDI 0183G 3.3.13 Interrupt Clear Register, = UARTICR @@ -263,13 +263,13 @@ pub(self) fn write( self.set_read_trigger(); } IMSC =3D> { - self.int_enabled =3D value; + self.int_enabled =3D Interrupt::from(value); return true; } RIS =3D> {} MIS =3D> {} ICR =3D> { - self.int_level &=3D !value; + self.int_level &=3D !Interrupt::from(value); return true; } DMACR =3D> { @@ -295,7 +295,7 @@ fn read_data_register(&mut self, update: &mut bool) -> = u32 { self.flags.set_receive_fifo_empty(true); } if self.read_count + 1 =3D=3D self.read_trigger { - self.int_level &=3D !Interrupt::RX.0; + self.int_level &=3D !Interrupt::RX; } self.receive_status_error_clear.set_from_data(c); *update =3D true; @@ -305,7 +305,7 @@ fn read_data_register(&mut self, update: &mut bool) -> = u32 { fn write_data_register(&mut self, value: u32) -> bool { // interrupts always checked let _ =3D self.loopback_tx(value.into()); - self.int_level |=3D Interrupt::TX.0; + self.int_level |=3D Interrupt::TX; true } =20 @@ -361,19 +361,19 @@ fn loopback_mdmctrl(&mut self) -> bool { // Change interrupts based on updated FR let mut il =3D self.int_level; =20 - il &=3D !Interrupt::MS.0; + il &=3D !Interrupt::MS; =20 if self.flags.data_set_ready() { - il |=3D Interrupt::DSR.0; + il |=3D Interrupt::DSR; } if self.flags.data_carrier_detect() { - il |=3D Interrupt::DCD.0; + il |=3D Interrupt::DCD; } if self.flags.clear_to_send() { - il |=3D Interrupt::CTS.0; + il |=3D Interrupt::CTS; } if self.flags.ring_indicator() { - il |=3D Interrupt::RI.0; + il |=3D Interrupt::RI; } self.int_level =3D il; true @@ -391,8 +391,8 @@ pub fn reset(&mut self) { self.line_control.reset(); self.receive_status_error_clear.reset(); self.dmacr =3D 0; - self.int_enabled =3D 0; - self.int_level =3D 0; + self.int_enabled =3D 0.into(); + self.int_level =3D 0.into(); self.ilpr =3D 0; self.ibrd =3D 0; self.fbrd =3D 0; @@ -451,7 +451,7 @@ pub fn fifo_rx_put(&mut self, value: registers::Data) -= > bool { } =20 if self.read_count =3D=3D self.read_trigger { - self.int_level |=3D Interrupt::RX.0; + self.int_level |=3D Interrupt::RX; return true; } false @@ -632,7 +632,7 @@ fn update(&self) { let regs =3D self.regs.borrow(); let flags =3D regs.int_level & regs.int_enabled; for (irq, i) in self.interrupts.iter().zip(IRQMASK) { - irq.set(flags & i !=3D 0); + irq.set(flags.any_set(i)); } } =20 @@ -642,14 +642,13 @@ pub fn post_load(&self, _version_id: u32) -> Result<(= ), ()> { } =20 /// Which bits in the interrupt status matter for each outbound IRQ line ? -const IRQMASK: [u32; 6] =3D [ - /* combined IRQ */ - Interrupt::E.0 | Interrupt::MS.0 | Interrupt::RT.0 | Interrupt::TX.0 |= Interrupt::RX.0, - Interrupt::RX.0, - Interrupt::TX.0, - Interrupt::RT.0, - Interrupt::MS.0, - Interrupt::E.0, +const IRQMASK: [Interrupt; 6] =3D [ + Interrupt::all(), + Interrupt::RX, + Interrupt::TX, + Interrupt::RT, + Interrupt::MS, + Interrupt::E, ]; =20 /// # Safety diff --git a/rust/hw/char/pl011/src/registers.rs b/rust/hw/char/pl011/src/r= egisters.rs index 690feb63785..7ececd39f86 100644 --- a/rust/hw/char/pl011/src/registers.rs +++ b/rust/hw/char/pl011/src/registers.rs @@ -9,7 +9,8 @@ // https://developer.arm.com/documentation/ddi0183/latest/ =20 use bilge::prelude::*; -use qemu_api::impl_vmstate_bitsized; +use bits::bits; +use qemu_api::{impl_vmstate_bitsized, impl_vmstate_forward}; =20 /// Offset of each register from the base memory address of the device. #[doc(alias =3D "offset")] @@ -326,22 +327,24 @@ fn default() -> Self { } } =20 -/// Interrupt status bits in UARTRIS, UARTMIS, UARTIMSC -pub struct Interrupt(pub u32); +bits! { + /// Interrupt status bits in UARTRIS, UARTMIS, UARTIMSC + #[derive(Default)] + pub struct Interrupt(u32) { + OE =3D 1 << 10, + BE =3D 1 << 9, + PE =3D 1 << 8, + FE =3D 1 << 7, + RT =3D 1 << 6, + TX =3D 1 << 5, + RX =3D 1 << 4, + DSR =3D 1 << 3, + DCD =3D 1 << 2, + CTS =3D 1 << 1, + RI =3D 1 << 0, =20 -impl Interrupt { - pub const OE: Self =3D Self(1 << 10); - pub const BE: Self =3D Self(1 << 9); - pub const PE: Self =3D Self(1 << 8); - pub const FE: Self =3D Self(1 << 7); - pub const RT: Self =3D Self(1 << 6); - pub const TX: Self =3D Self(1 << 5); - pub const RX: Self =3D Self(1 << 4); - pub const DSR: Self =3D Self(1 << 3); - pub const DCD: Self =3D Self(1 << 2); - pub const CTS: Self =3D Self(1 << 1); - pub const RI: Self =3D Self(1 << 0); - - pub const E: Self =3D Self(Self::OE.0 | Self::BE.0 | Self::PE.0 | Self= ::FE.0); - pub const MS: Self =3D Self(Self::RI.0 | Self::DSR.0 | Self::DCD.0 | S= elf::CTS.0); + E =3D bits!(Self as u32: OE | BE | PE | FE), + MS =3D bits!(Self as u32: RI | DSR | DCD | CTS), + } } +impl_vmstate_forward!(Interrupt); --=20 2.49.0 From nobody Sun Dec 14 02:01:12 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1747815594; cv=none; d=zohomail.com; s=zohoarc; b=ad6Ws6WmKIpmhSbPkC+txLAGCx6TuHvWm5Yvyj7/rYMTFtKW/Ndh3z6bXeoTvZbe1QRuQS6pjhiVw/WLYY0Z2HIuZVKxoKogKhztXWp9bLWKH2RqkpMX/As2UsklJyMmFTpibmdPmJ/YZlDjvtux1KjGYARHJBl/+Z/fwiMpmyo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747815594; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=sm4FDV9XcvaUoJSoDVM8BTJfAISob2kgbvzU5BLD5+0=; b=UbiNDtWm6i8e2q6HDwlmgNz6Icv9NNiTiVDW4ncZjMhJDF9avTUVXnVY30fN6lmW9QwMqJBdjviqVtgwR1UUzAkirnavGg2YFgZTcjDqiRHF/kKdVggwWSKCfd91lzmcYGoWuGZYM6GJtfgc9MMbyyY6U/SDZ/eNfm9OOSPkFIQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 17478155944881022.0981238210668; Wed, 21 May 2025 01:19:54 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHefW-0004s8-Py; Wed, 21 May 2025 04:19:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHefK-0004nR-HL for qemu-devel@nongnu.org; Wed, 21 May 2025 04:19:06 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHefD-0000B3-Sp for qemu-devel@nongnu.org; Wed, 21 May 2025 04:19:05 -0400 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-248-yRrH88Y5MZadLjgR_byZZQ-1; Wed, 21 May 2025 04:18:57 -0400 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-442fa43e018so28565945e9.0 for ; Wed, 21 May 2025 01:18:57 -0700 (PDT) Received: from [192.168.122.1] ([151.95.46.79]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3a35ca5a87fsm18560962f8f.29.2025.05.21.01.18.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 May 2025 01:18:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747815538; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sm4FDV9XcvaUoJSoDVM8BTJfAISob2kgbvzU5BLD5+0=; b=Pjsj0hsI07+Hp293T3xg4JOlcRUuHbuDb3ZKuff3SrY0yPXaxY5hmy1b74YRKK/DdCEEPC oYxkt7brOfqnvAc+/ltKTXJp/1J0gpd5fVS1CLFtxLs7wp0Qs4OA9qa43qeg8i4znwP84o 9j1Sy85MN+QCvZlqM4uy5U0/q0cprX4= X-MC-Unique: yRrH88Y5MZadLjgR_byZZQ-1 X-Mimecast-MFC-AGG-ID: yRrH88Y5MZadLjgR_byZZQ_1747815536 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747815535; x=1748420335; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sm4FDV9XcvaUoJSoDVM8BTJfAISob2kgbvzU5BLD5+0=; b=uYumNuS3VIV2NW5zbRTpRgKxJz+cn352IpHtL7ZJ0S+X1Eq3XRch9sOXF6YxOyCY7O hE+sCqgM67sMZ16z9CMlqyAy3+nqpLaOPLOe2Hm6UDY2rWlRVvAtm1Wh7rUiOZfGPDrK erO1MCd4fky2Ia8LSB23ISX1yNci50NLb8d8/T0dlpa3iWKA43yGHc3lo6kH3U7GEZHr GWC8qZz9JUFaDWIFFLleP5ENketEBCoewFrFoZljVVbZOLpBJS/GQ4wh9M6Iq/7hSlVV bReGZ/U1/z3Wj0IgnAQGZf2mWsyMmq3f40Mkqqilp8WbUIwSS5YwFfvTmtaVlW02kUvR WyyA== X-Gm-Message-State: AOJu0YzmplnaiAZFBEmkRZ1F7N+Zy6G8KvB9JNp3ROB3/S2Xj1X8o2JI KwhxEAgNpu9e6jk+ECzLePk04XUo7J15CBdp6X7DeNBzkY7VwHEl3W/iXDqquAq5Q4roJprld/d YwiJZm6hCVS7QGJTiQCMJvy7nkaPElB4jHfhxN+HQ4cd/yqRfFeD27ZliB5qCa4sWx9SmDqmbIJ N0UcrnwHxvq4KOoIX+cxZcZb5N8tP/j2iyGEIxlOPu X-Gm-Gg: ASbGncusP7WFcbabRvJlo3hL5AxQrh1tlIQPCPPjLC+HVFKp/Mdd/yAXMwixLsVZiKU UINsmer1Xg7Gmjp66cveQixM5+S76BX+t0U16d9pX2MkiYGMjpkTpENMf6JDmkhPipKdN9KjdWH rOuEqIovXhl0Uq8uKF6rv//E4kdteubLtd/YwUCsYxjR0LIeN/JYlvR5OLvyJaqJhcAB01EBLD5 69Fywr0QDzLe0GRObClaaCtAKmP/oqCQ3U9lm2LRMuePAriQF17oYoUhJPUOnFDogclWpKZ+lQR EQuWlFb9ilhO7g== X-Received: by 2002:a05:600c:3e8d:b0:43d:174:2668 with SMTP id 5b1f17b1804b1-442f844e5d4mr208404045e9.0.1747815535301; Wed, 21 May 2025 01:18:55 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFcK8YTwPUKcO65rs2si2DQU9nhEw3TQ5CTI6CUM2IeHnAm8wcOmtgnkQnf+sn8QKK4TIOxHw== X-Received: by 2002:a05:600c:3e8d:b0:43d:174:2668 with SMTP id 5b1f17b1804b1-442f844e5d4mr208403745e9.0.1747815534893; Wed, 21 May 2025 01:18:54 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, qemu-rust@nongnu.org, manos.pitsidianakis@linaro.org Subject: [RFC PATCH 3/6] rust: qemu-api-macros: add from_bits and into_bits to #[derive(TryInto)] Date: Wed, 21 May 2025 10:18:42 +0200 Message-ID: <20250521081845.496442-4-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250521081845.496442-1-pbonzini@redhat.com> References: <20250521081845.496442-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.487, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1747815595301116600 Content-Type: text/plain; charset="utf-8" These const functions make it possible to use enums easily together with the bitfield-struct crate. Signed-off-by: Paolo Bonzini --- rust/qemu-api-macros/src/lib.rs | 48 ++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/rust/qemu-api-macros/src/lib.rs b/rust/qemu-api-macros/src/lib= .rs index ceb79f09f97..103470785e3 100644 --- a/rust/qemu-api-macros/src/lib.rs +++ b/rust/qemu-api-macros/src/lib.rs @@ -193,23 +193,51 @@ fn get_variants(input: &DeriveInput) -> Result<&Punct= uated, Macr } =20 #[rustfmt::skip::macros(quote)] -fn derive_tryinto_or_error(input: DeriveInput) -> Result { - let repr =3D get_repr_uN(&input, "#[derive(TryInto)]")?; - - let name =3D &input.ident; - let variants =3D get_variants(&input)?; +fn derive_tryinto_body( + name: &Ident, + variants: &Punctuated, + repr: &Path, +) -> Result { let discriminants: Vec<&Ident> =3D variants.iter().map(|f| &f.ident).c= ollect(); =20 Ok(quote! { + #(const #discriminants: #repr =3D #name::#discriminants as #repr;)= *; + match value { + #(#discriminants =3D> Ok(#name::#discriminants),)* + _ =3D> Err(value), + } + }) +} + +#[rustfmt::skip::macros(quote)] +fn derive_tryinto_or_error(input: DeriveInput) -> Result { + let repr =3D get_repr_uN(&input, "#[derive(TryInto)]")?; + let name =3D &input.ident; + let body =3D derive_tryinto_body(name, get_variants(&input)?, &repr)?; + let errmsg =3D format!("invalid value for {name}"); + + Ok(quote! { + impl #name { + #[allow(dead_code)] + pub const fn into_bits(self) -> #repr { + self as #repr + } + + #[allow(dead_code)] + pub const fn from_bits(value: #repr) -> Self { + match ({ + #body + }) { + Ok(x) =3D> x, + Err(_) =3D> panic!(#errmsg) + } + } + } impl core::convert::TryFrom<#repr> for #name { type Error =3D #repr; =20 fn try_from(value: #repr) -> Result { - #(const #discriminants: #repr =3D #name::#discriminants as= #repr;)*; - match value { - #(#discriminants =3D> Ok(Self::#discriminants),)* - _ =3D> Err(value), - } + #body } } }) --=20 2.49.0 From nobody Sun Dec 14 02:01:12 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1747815668; cv=none; d=zohomail.com; s=zohoarc; b=mrX//g7XFkmNfIAuh2KlhuTKJ/fsub99Vv6Na5TX3BZ7Wg9aBjdsDc+ll+CnqwNJnxeGrsSbEqtuNw2c5ChNGP+lPNhvn5oViQVa4dtRPcdOTT9sjz9LBLoykQlp38ObPxi32CiaGbCRhAbUw8X2KR4WkaBopyhbQW57O8/vWBo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747815668; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=vi+4q+DuQzXZ0fGkhLusAtF/e0P3HvxStkXaBrSnrE4=; b=lOlsT1u0B2QX45GrCGoY6tbtXUNoiK8By19rFFqO49eWbDOeqj3D1Gr5caqUnuSnUefu+iDJjzT1TdmknLjP/p+MyKf0iMaaqoiDYNzR2fUJXPmm5nymnQLXLQKzDXYa6CcpwNbitJ3hQ1as8HOaNaRdojyAPnz7adA8P4+2Gsk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 17478156685751007.360063272066; Wed, 21 May 2025 01:21:08 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHefY-0004sG-Mj; Wed, 21 May 2025 04:19:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHefN-0004oR-IA for qemu-devel@nongnu.org; Wed, 21 May 2025 04:19:11 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHefI-0000Bk-El for qemu-devel@nongnu.org; Wed, 21 May 2025 04:19:07 -0400 Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-296-QEU0NnXjO-eexIpeZCx7IQ-1; Wed, 21 May 2025 04:19:00 -0400 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-3a364d2d0efso2278105f8f.3 for ; Wed, 21 May 2025 01:19:00 -0700 (PDT) Received: from [192.168.122.1] ([151.95.46.79]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3a35ca5aba3sm18586266f8f.40.2025.05.21.01.18.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 May 2025 01:18:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747815541; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vi+4q+DuQzXZ0fGkhLusAtF/e0P3HvxStkXaBrSnrE4=; b=JB+JZbjgiUk+ObPnAwvQDQThT4U+1xFvHuGHd1tRdgzyOF/o0NKYhupi8KuZ+3v0f80GB/ 9icjtBJyPC08b1qBDfHlDKEz+8Vod/h0YGzPfgv2dZGa8vhQOYeKfZ2sO6jfAujDIH255q JoEU/Oq9diVxXFoRam/SP7tVe5DpHSY= X-MC-Unique: QEU0NnXjO-eexIpeZCx7IQ-1 X-Mimecast-MFC-AGG-ID: QEU0NnXjO-eexIpeZCx7IQ_1747815539 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747815538; x=1748420338; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vi+4q+DuQzXZ0fGkhLusAtF/e0P3HvxStkXaBrSnrE4=; b=f99dSmBFhJi6I4fn2b61HkRyHWyNSmhWybPlge/IAP/GM0WLoiTCpJ9BfyKKqkBueN mDO7WWtA3LBcNt8W7dV3GNsoZiatcMB9HAs7cJLRc5ioNGuHielQLSBFmwXH82cFyiqu sZNCi8nybBz/IRMXf3h63NiplJbPVVsYLx2mC2nQSc3qgyjHbWLZPGKAM3YJKAYdIMwd yxQpCptXYsjmV5POc+t/nuAzHUd6n4pBAU8XnP1JI513FqdorzYP05bQFhW5FYLHpkBd NMFMnRJgXGbG4lhaZdI9veHXFa56FWstPVEu6IRqzzkZI8LieTinzwvrSEy5FDvnVLAR JQsA== X-Gm-Message-State: AOJu0Yy3oLbpPy20Byifs8NN5ejQ2P7r0tuSeQmsfrEYwRoYPylCt5Xq hKLk5kMc1BylzpYFXTnE5j5DWiElLU81BxVKGq4ymbOoWeIVm03s2u9hRh1pw1co2WI4UPjGRZo 0Ti+YyXVc5JAjMmuNnE9j78xIvP6l1/L2MxP5ibD3jHIzaoNIq7RbiVRznWTPUUzJNTNByIv+xn cioRVc6Mk0/uyDeByvYAtLLmRbE2R92G9zSMwsP0GM X-Gm-Gg: ASbGnctKFO/RxOX+mFF9NWSeVyV8PDmtyUM23EZeHd+fc7j/Fk1ZGDLJqdgYQAb+e8e t1aRhKcO4CrMlBSWEOK2nGN6Y3mDNoyaWWbQic5C3acfqUFh5KwnNkSOfBVjPqIYKeee9lIVfEQ U0Hem3B/ogSOEi6MNmmquNNTS4ASNs2/PByg5vljygbSdI+JNUVMp5/8b0E3/VTDmb0znQ9cuNq tBa7rYeI7RDL3JW0fcbY/TjKbI9xVm2HCqc6ebicllA6LwfcBTnkwkZ9L5lgkbE/5Gk3DavRmi2 4+aITA7U4rXuww== X-Received: by 2002:a05:6000:178c:b0:3a3:671e:3b7c with SMTP id ffacd0b85a97d-3a3671e3c09mr13633138f8f.48.1747815537933; Wed, 21 May 2025 01:18:57 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE5/Qifu/phEJO+eeNN2LYJDlQEQdW78L1t3/lI3cccD9T9g03PDze6s8YhzFAFetysJ0VAnQ== X-Received: by 2002:a05:6000:178c:b0:3a3:671e:3b7c with SMTP id ffacd0b85a97d-3a3671e3c09mr13633102f8f.48.1747815537417; Wed, 21 May 2025 01:18:57 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, qemu-rust@nongnu.org, manos.pitsidianakis@linaro.org Subject: [RFC PATCH 4/6] rust: subprojects: add bitfield-struct Date: Wed, 21 May 2025 10:18:43 +0200 Message-ID: <20250521081845.496442-5-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250521081845.496442-1-pbonzini@redhat.com> References: <20250521081845.496442-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.487, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1747815670464116600 Content-Type: text/plain; charset="utf-8" The bitfield-struct is much smaller than "bilge" and supports "const" expressions better. The main disadvantage is that it does not let you annotate enums as bitfields and does not integrate with arbitrary-int, thus requiring manual size annotations for anything that is not a bool, iNN or uNN. Lack of support for arbitrary-int is a very minor change; enums are a bit more annoying because they require manual implementation of two functions from_bits() and into_bits(); however, that is already handled by QEMU's bits! and #[derive(qemu_api_macros::TryInto)] utilities. Together, these basically make the manual work go away. Signed-off-by: Paolo Bonzini --- rust/meson.build | 3 ++ subprojects/.gitignore | 1 + subprojects/bitfield-struct-0.9-rs.wrap | 7 ++++ .../bitfield-struct-0.9-rs/meson.build | 36 +++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 subprojects/bitfield-struct-0.9-rs.wrap create mode 100644 subprojects/packagefiles/bitfield-struct-0.9-rs/meson.b= uild diff --git a/rust/meson.build b/rust/meson.build index f370b0ec939..58f14a70d6d 100644 --- a/rust/meson.build +++ b/rust/meson.build @@ -1,3 +1,6 @@ +subproject('bitfield-struct-0.9-rs', required: true) +bitfield_struct_dep =3D dependency('bitfield-struct-0.9-rs') + subdir('qemu-api-macros') subdir('bits') subdir('qemu-api') diff --git a/subprojects/.gitignore b/subprojects/.gitignore index d12d34618cc..180c3134864 100644 --- a/subprojects/.gitignore +++ b/subprojects/.gitignore @@ -9,6 +9,7 @@ /arbitrary-int-1.2.7 /bilge-0.2.0 /bilge-impl-0.2.0 +/bitfield-struct-0.9.5 /either-1.12.0 /itertools-0.11.0 /libc-0.2.162 diff --git a/subprojects/bitfield-struct-0.9-rs.wrap b/subprojects/bitfield= -struct-0.9-rs.wrap new file mode 100644 index 00000000000..dfdbbc853af --- /dev/null +++ b/subprojects/bitfield-struct-0.9-rs.wrap @@ -0,0 +1,7 @@ +[wrap-file] +directory =3D bitfield-struct-0.9.5 +source_url =3D https://crates.io/api/v1/crates/bitfield-struct/0.9.5/downl= oad +source_filename =3D bitfield-struct-0.9.5.tar.gz +source_hash =3D b2869c63ccf4f8bf0d485070b880e60e097fb7aeea80ee82a0a94a957e= 372a0b +#method =3D cargo +patch_directory =3D bitfield-struct-0.9-rs diff --git a/subprojects/packagefiles/bitfield-struct-0.9-rs/meson.build b/= subprojects/packagefiles/bitfield-struct-0.9-rs/meson.build new file mode 100644 index 00000000000..e8badb7da18 --- /dev/null +++ b/subprojects/packagefiles/bitfield-struct-0.9-rs/meson.build @@ -0,0 +1,36 @@ +project('bitfield-struct-0.9-rs', 'rust', + meson_version: '>=3D1.5.0', + version: '0.9.5', + license: 'MIT', + default_options: []) + +subproject('quote-1-rs', required: true) +subproject('syn-2-rs', required: true) +subproject('proc-macro2-1-rs', required: true) + +quote_dep =3D dependency('quote-1-rs', native: true) +syn_dep =3D dependency('syn-2-rs', native: true) +proc_macro2_dep =3D dependency('proc-macro2-1-rs', native: true) + +rust =3D import('rust') + +_bitfield_struct_rs =3D rust.proc_macro( + 'bitfield_struct', + files('src/lib.rs'), + override_options: ['rust_std=3D2021', 'build.rust_std=3D2021'], + rust_args: [ + '--cap-lints', 'allow', + '--cfg', 'use_fallback', + ], + dependencies: [ + quote_dep, + syn_dep, + proc_macro2_dep, + ], +) + +bitfield_struct_dep =3D declare_dependency( + link_with: _bitfield_struct_rs, +) + +meson.override_dependency('bitfield-struct-0.9-rs', bitfield_struct_dep) --=20 2.49.0 From nobody Sun Dec 14 02:01:12 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1747815659; cv=none; d=zohomail.com; s=zohoarc; b=FztKspvagZtUzNbtswB/9PpRaWFjgf8yyFn3CflDjK5e+GVCJa1sWavoMz9/Bg7wcEf2ItwChEtGlQXDijF53h9j6CLyzFxzK+L8Mgu06bMFzfq4+kg2MFsmqMuOkfSqNr8gDBWCRNd2eV6RDNP5fe+l1o/NeyFiOn9bUlXr31w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747815659; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=AR66GhTpeyumQSu0KfASdH7/iMoNc4vAxdPN0ZdynH8=; b=hl3R2DNTvr8jnCD5F7f4VP2V1zv4JT6krcESpQllJ7Zo/NyW3i75rRdxo0qd0f9IxojCYY8kHKBzdyylUddOhemDUNmwvjuVp7CXnaEluvzivQSk/gQASShYX4AFawwbi0kGO5bVqQKYt66K5iJqaVGuWR3ejxkBJoXoYIGrJtY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747815659821736.9408392885641; Wed, 21 May 2025 01:20:59 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHefd-0004uP-Nu; Wed, 21 May 2025 04:19:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHefS-0004px-1n for qemu-devel@nongnu.org; Wed, 21 May 2025 04:19:14 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHefK-0000Cw-G0 for qemu-devel@nongnu.org; Wed, 21 May 2025 04:19:13 -0400 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-410-HgGAY0YyNn6ulVCjJVAmpg-1; Wed, 21 May 2025 04:19:03 -0400 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-43d4d15058dso19653115e9.0 for ; Wed, 21 May 2025 01:19:03 -0700 (PDT) Received: from [192.168.122.1] ([151.95.46.79]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-447f3dd9c21sm62787015e9.38.2025.05.21.01.18.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 May 2025 01:18:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747815545; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AR66GhTpeyumQSu0KfASdH7/iMoNc4vAxdPN0ZdynH8=; b=ZavilYCAD7/CK7gnpyge0oLt5HeZshfNLJSI6DxxyiizKVHXgj7SgElMNwoPZcsUcDSqE+ at7SPBT8xrm/2w37mAIKSvA4UFHucl/SaOl2h0yrghYrOCvELCHmGWc2TTVJxGLm2dDkDF 8VhdORicYfvBhC1xUdPLVEizwwLNLAQ= X-MC-Unique: HgGAY0YyNn6ulVCjJVAmpg-1 X-Mimecast-MFC-AGG-ID: HgGAY0YyNn6ulVCjJVAmpg_1747815542 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747815541; x=1748420341; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AR66GhTpeyumQSu0KfASdH7/iMoNc4vAxdPN0ZdynH8=; b=A4K9ZL0quik83C7VnU1KtVn4kKWK2RdFZU/XrXhY+jUGEK3eM51fIPPc9UNNgC3yBP /7nz7S8NAp0UsaukTciiWOo94+fNjSWaxPC4o63xFKaXNRHlHUdqRgnPKzZ2zKPsf3px UnEtmEN8QwYc30whM5RFrNDTEk4rhthn4DaPotJzZijognjoT7wvJLJ7MQD2HffC6oYa oq091C6tZKNXaGIjepxjQ9mq8UpThaUpAG5SDJ6X3SfIs/9xPymv5pypv9iBIxosnCiG Qm6WLOB7TFgGYNN8CygkNpSpieiuV2rCqotMgxygPQNeQM0qu0RLo73RUNgXC344EFOT G9IA== X-Gm-Message-State: AOJu0Yxqx6PFr0IlxRlY7e+9+88xUHtv1DMXJ3tquOfv8zROwx+EAiZD HVjzUSiaq0FadffMhTPtGvhPnYyePFKgDN4SJ5KzEwNzprLgKth9OAy+jpvIpmwBUMpDT+vbPci gy5GhsEnnnd1TarcQ8g57FYlGOWfjcNy7ukj/QtGsSewhi7/lthWCE4gZHJXoKr7KwiCHw0hK9W /d46+DHZhNw22Dsj2o+CYYHvNaroxmxBmiK6e/cmpy X-Gm-Gg: ASbGncuZ0NnzCFX1rUjruTAiKIyTVLFrwSkDQw4xzIhc2Rdonj3hHJlgGfa7H3HWazb waDMf0X4X9i+5GdPR0LhOpjSnArmN5tJWZ+A6c0eOQ0ZOwHxhGlFt3kYd3bEnUNuYNdRKY7jgkq rU7QlahVEA67JMqd9Z46WxsU+hOKWP8V+KLhNfthg6ELDsRay+sV2HGAKivq8VggCXZ9VAAhJaf S4xDp/jbinKROquGhg0kikJNVvWQugTw6ZHWHNHxlBx3aN1SCd8Bddc589pB5EjWfUgAsNSkcCq mCi7/cU05I5Ctg== X-Received: by 2002:a05:600c:a012:b0:43c:e70d:44f0 with SMTP id 5b1f17b1804b1-442fd63bfa4mr175851775e9.19.1747815540969; Wed, 21 May 2025 01:19:00 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFQT5Dg8m9YTAN1goqzsDzHeVtcSBdgBcKx4IECUHoeESE2p7eljMlVOA5UbzB7UwIMwTv5Vg== X-Received: by 2002:a05:600c:a012:b0:43c:e70d:44f0 with SMTP id 5b1f17b1804b1-442fd63bfa4mr175851395e9.19.1747815540408; Wed, 21 May 2025 01:19:00 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, qemu-rust@nongnu.org, manos.pitsidianakis@linaro.org Subject: [RFC PATCH 5/6] rust: pl011: switch from bilge to bitfield-struct Date: Wed, 21 May 2025 10:18:44 +0200 Message-ID: <20250521081845.496442-6-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250521081845.496442-1-pbonzini@redhat.com> References: <20250521081845.496442-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.487, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1747815662495116600 Content-Type: text/plain; charset="utf-8" The bilge crate, while very nice and espressive, is heavily reliant on traits; because trait functions are never const, bilge and const mix about as well as water and oil. Try using the bitfield-struct crate instead. It is built to support const very well and the only downside is that more manual annotations are needed (for enums and non-full-byte members). Otherwise, the use is pretty much the same and in fact device code does not change at all, only register declarations. Recent versions want to use Rust 1.83, so this uses a slightly older version with basically no lost functionality; but anyway, I want to switch to 1.83 for QEMU as well due to improved "const" support in the compiler. Signed-off-by: Paolo Bonzini --- rust/Cargo.toml | 1 + rust/hw/char/pl011/Cargo.toml | 3 +- rust/hw/char/pl011/meson.build | 11 +-- rust/hw/char/pl011/src/registers.rs | 108 ++++++++++++++-------------- 4 files changed, 56 insertions(+), 67 deletions(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 165328b6d01..3345858b5b4 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -97,5 +97,6 @@ used_underscore_binding =3D "deny" #wildcard_imports =3D "deny" # still have many bindings::* imports =20 # these may have false positives +enum_variant_names =3D "allow" #option_if_let_else =3D "deny" cognitive_complexity =3D "deny" diff --git a/rust/hw/char/pl011/Cargo.toml b/rust/hw/char/pl011/Cargo.toml index 003ef9613d4..97e3dd00c35 100644 --- a/rust/hw/char/pl011/Cargo.toml +++ b/rust/hw/char/pl011/Cargo.toml @@ -16,8 +16,7 @@ rust-version.workspace =3D true crate-type =3D ["staticlib"] =20 [dependencies] -bilge =3D { version =3D "0.2.0" } -bilge-impl =3D { version =3D "0.2.0" } +bitfield-struct =3D { version =3D "0.9" } bits =3D { path =3D "../../../bits" } qemu_api =3D { path =3D "../../../qemu-api" } qemu_api_macros =3D { path =3D "../../../qemu-api-macros" } diff --git a/rust/hw/char/pl011/meson.build b/rust/hw/char/pl011/meson.build index f134a6cdc6b..1bae5a03310 100644 --- a/rust/hw/char/pl011/meson.build +++ b/rust/hw/char/pl011/meson.build @@ -1,17 +1,10 @@ -subproject('bilge-0.2-rs', required: true) -subproject('bilge-impl-0.2-rs', required: true) - -bilge_dep =3D dependency('bilge-0.2-rs') -bilge_impl_dep =3D dependency('bilge-impl-0.2-rs') - _libpl011_rs =3D static_library( 'pl011', files('src/lib.rs'), override_options: ['rust_std=3D2021', 'build.rust_std=3D2021'], rust_abi: 'rust', dependencies: [ - bilge_dep, - bilge_impl_dep, + bitfield_struct_dep, bits_rs, qemu_api, qemu_api_macros, @@ -22,6 +15,6 @@ rust_devices_ss.add(when: 'CONFIG_X_PL011_RUST', if_true:= [declare_dependency( link_whole: [_libpl011_rs], # Putting proc macro crates in `dependencies` is necessary for Meson to = find # them when compiling the root per-target static rust lib. - dependencies: [bilge_impl_dep, qemu_api_macros], + dependencies: [bitfield_struct_dep, qemu_api_macros], variables: {'crate': 'pl011'}, )]) diff --git a/rust/hw/char/pl011/src/registers.rs b/rust/hw/char/pl011/src/r= egisters.rs index 7ececd39f86..f2138c637c5 100644 --- a/rust/hw/char/pl011/src/registers.rs +++ b/rust/hw/char/pl011/src/registers.rs @@ -5,12 +5,16 @@ //! Device registers exposed as typed structs which are backed by arbitrary //! integer bitmaps. [`Data`], [`Control`], [`LineControl`], etc. =20 +// rustc prefers "constant-like" enums to use upper case names, but that +// is inconsistent in its own way. +#![allow(non_upper_case_globals)] + // For more detail see the PL011 Technical Reference Manual DDI0183: // https://developer.arm.com/documentation/ddi0183/latest/ =20 -use bilge::prelude::*; +use bitfield_struct::bitfield; use bits::bits; -use qemu_api::{impl_vmstate_bitsized, impl_vmstate_forward}; +use qemu_api::impl_vmstate_forward; =20 /// Offset of each register from the base memory address of the device. #[doc(alias =3D "offset")] @@ -78,14 +82,18 @@ pub enum RegisterOffset { /// The `UARTRSR` register is updated only when a read occurs /// from the `UARTDR` register with the same status information /// that can also be obtained by reading the `UARTDR` register -#[bitsize(8)] -#[derive(Clone, Copy, Default, DebugBits, FromBits)] +#[bitfield(u8)] pub struct Errors { pub framing_error: bool, pub parity_error: bool, pub break_error: bool, pub overrun_error: bool, - _reserved_unpredictable: u4, + #[bits(4)] + _reserved_unpredictable: u8, +} + +impl Errors { + pub const BREAK: Self =3D Errors::new().with_break_error(true); } =20 /// Data Register, `UARTDR` @@ -93,19 +101,18 @@ pub struct Errors { /// The `UARTDR` register is the data register; write for TX and /// read for RX. It is a 12-bit register, where bits 7..0 are the /// character and bits 11..8 are error bits. -#[bitsize(32)] -#[derive(Clone, Copy, Default, DebugBits, FromBits)] +#[bitfield(u32)] #[doc(alias =3D "UARTDR")] pub struct Data { pub data: u8, + #[bits(8)] pub errors: Errors, _reserved: u16, } -impl_vmstate_bitsized!(Data); +impl_vmstate_forward!(Data); =20 impl Data { - // bilge is not very const-friendly, unfortunately - pub const BREAK: Self =3D Self { value: 1 << 10 }; + pub const BREAK: Self =3D Self::new().with_errors(Errors::BREAK); } =20 /// Receive Status Register / Error Clear Register, `UARTRSR/UARTECR` @@ -119,13 +126,14 @@ impl Data { /// and UARTECR for writes, but really it's a single error status /// register where writing anything to the register clears the error /// bits. -#[bitsize(32)] -#[derive(Clone, Copy, DebugBits, FromBits)] +#[bitfield(u32)] pub struct ReceiveStatusErrorClear { + #[bits(8)] pub errors: Errors, - _reserved_unpredictable: u24, + #[bits(24)] + _reserved_unpredictable: u32, } -impl_vmstate_bitsized!(ReceiveStatusErrorClear); +impl_vmstate_forward!(ReceiveStatusErrorClear); =20 impl ReceiveStatusErrorClear { pub fn set_from_data(&mut self, data: Data) { @@ -138,14 +146,7 @@ pub fn reset(&mut self) { } } =20 -impl Default for ReceiveStatusErrorClear { - fn default() -> Self { - 0.into() - } -} - -#[bitsize(32)] -#[derive(Clone, Copy, DebugBits, FromBits)] +#[bitfield(u32, default =3D false)] /// Flag Register, `UARTFR` /// /// This has the usual inbound RS232 modem-control signals, plus flags @@ -171,9 +172,10 @@ pub struct Flags { pub transmit_fifo_empty: bool, /// RI: Ring indicator pub ring_indicator: bool, - _reserved_zero_no_modify: u23, + #[bits(23)] + _reserved_zero_no_modify: u32, } -impl_vmstate_bitsized!(Flags); +impl_vmstate_forward!(Flags); =20 impl Flags { pub fn reset(&mut self) { @@ -183,16 +185,14 @@ pub fn reset(&mut self) { =20 impl Default for Flags { fn default() -> Self { - let mut ret: Self =3D 0.into(); // After reset TXFF, RXFF, and BUSY are 0, and TXFE and RXFE are 1 - ret.set_receive_fifo_empty(true); - ret.set_transmit_fifo_empty(true); - ret + Self::from(0) + .with_receive_fifo_empty(true) + .with_transmit_fifo_empty(true) } } =20 -#[bitsize(32)] -#[derive(Clone, Copy, DebugBits, FromBits)] +#[bitfield(u32)] /// Line Control Register, `UARTLCR_H` #[doc(alias =3D "UARTLCR_H")] pub struct LineControl { @@ -201,48 +201,46 @@ pub struct LineControl { /// PEN: Parity enable pub parity_enabled: bool, /// EPS: Even parity select + #[bits(1)] pub parity: Parity, /// STP2: Two stop bits select pub two_stops_bits: bool, /// FEN: Enable FIFOs + #[bits(1)] pub fifos_enabled: Mode, /// WLEN: Word length in bits /// b11 =3D 8 bits /// b10 =3D 7 bits /// b01 =3D 6 bits /// b00 =3D 5 bits. + #[bits(2)] pub word_length: WordLength, /// SPS Stick parity select pub sticky_parity: bool, /// 31:8 - Reserved, do not modify, read as zero. - _reserved_zero_no_modify: u24, + #[bits(24)] + _reserved_zero_no_modify: u32, } -impl_vmstate_bitsized!(LineControl); +impl_vmstate_forward!(LineControl); =20 impl LineControl { pub fn reset(&mut self) { // All the bits are cleared to 0 when reset. - *self =3D 0.into(); + *self =3D Self::default(); } } =20 -impl Default for LineControl { - fn default() -> Self { - 0.into() - } -} - -#[bitsize(1)] -#[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] /// `EPS` "Even parity select", field of [Line Control /// register](LineControl). +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, qemu_api_macros::TryInto)] pub enum Parity { Odd =3D 0, Even =3D 1, } =20 -#[bitsize(1)] -#[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, qemu_api_macros::TryInto)] /// `FEN` "Enable FIFOs" or Device mode, field of [Line Control /// register](LineControl). pub enum Mode { @@ -253,8 +251,8 @@ pub enum Mode { FIFO =3D 1, } =20 -#[bitsize(2)] -#[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, qemu_api_macros::TryInto)] /// `WLEN` Word length, field of [Line Control register](LineControl). /// /// These bits indicate the number of data bits transmitted or received in= a @@ -275,9 +273,8 @@ pub enum WordLength { /// The `UARTCR` register is the control register. It contains various /// enable bits, and the bits to write to set the usual outbound RS232 /// modem control signals. All bits reset to 0 except TXE and RXE. -#[bitsize(32)] +#[bitfield(u32, default =3D false)] #[doc(alias =3D "UARTCR")] -#[derive(Clone, Copy, DebugBits, FromBits)] pub struct Control { /// `UARTEN` UART enable: 0 =3D UART is disabled. pub enable_uart: bool, @@ -285,9 +282,10 @@ pub struct Control { /// QEMU does not model this. pub enable_sir: bool, /// `SIRLP` SIR low-power IrDA mode. QEMU does not model this. - pub sir_lowpower_irda_mode: u1, + pub sir_lowpower_irda_mode: bool, /// Reserved, do not modify, read as zero. - _reserved_zero_no_modify: u4, + #[bits(4)] + _reserved_zero_no_modify: u8, /// `LBE` Loopback enable: feed UART output back to the input pub enable_loopback: bool, /// `TXE` Transmit enable @@ -309,21 +307,19 @@ pub struct Control { /// 31:16 - Reserved, do not modify, read as zero. _reserved_zero_no_modify2: u16, } -impl_vmstate_bitsized!(Control); +impl_vmstate_forward!(Control); =20 impl Control { pub fn reset(&mut self) { - *self =3D 0.into(); - self.set_enable_receive(true); - self.set_enable_transmit(true); + *self =3D Self::default(); } } =20 impl Default for Control { fn default() -> Self { - let mut ret: Self =3D 0.into(); - ret.reset(); - ret + Self::from(0) + .with_enable_receive(true) + .with_enable_transmit(true) } } =20 --=20 2.49.0 From nobody Sun Dec 14 02:01:12 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1747815632; cv=none; d=zohomail.com; s=zohoarc; b=I9zLfxNhSQT5lmGCMz4SpBWB+//mpvHgox7hKQNaAoaz3yIhPPf3h8HR4GHfeKcfrMlqPJzEg0EMlAj33FQBN7b//rJPYOLp2DWfLLRwxIq2Ew7B0bllgQ+O6mOalEICg53/fFuPFtRJ0/35u6AzgFjBWcQrNdlOkHuOLiICdno= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747815632; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=DYNNR8kxdpigAzsfIWV54lNrAJSCQ81aFM7IBOhn2ic=; b=Q/HroS8Qc/v4iZr7sFrtv/ohtDwVEDK4ldhdmldZ/JgaBRKkwZlAk0tn03QQhB8utzUKxqG6EnAIOP9a1LkPLxzNacrmF8Vhr0kIOAW6xoqKIZprOtgMrdXsDIdDdjrQMM08GMi60gOIY1MCruHjg42uV3MKkoAJnBH6KdYVbr4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747815632583320.2533151593534; Wed, 21 May 2025 01:20:32 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHefe-0004uv-KH; Wed, 21 May 2025 04:19:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHefU-0004qs-91 for qemu-devel@nongnu.org; Wed, 21 May 2025 04:19:16 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHefM-0000DX-Ds for qemu-devel@nongnu.org; Wed, 21 May 2025 04:19:15 -0400 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-275-fkmscUJxPdq_ST0gwrOPtA-1; Wed, 21 May 2025 04:19:03 -0400 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43cf446681cso39564465e9.1 for ; Wed, 21 May 2025 01:19:03 -0700 (PDT) Received: from [192.168.122.1] ([151.95.46.79]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3a36749f622sm15154505f8f.93.2025.05.21.01.19.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 May 2025 01:19:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747815546; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DYNNR8kxdpigAzsfIWV54lNrAJSCQ81aFM7IBOhn2ic=; b=JqGSB6IBDdVBkEFFYzLTt2eLt4B3uMVBuipBrATyDT7PWI5nBVyZ/e/sUMAJV3JTvm+cXW J6fosvPoFXJZikNzH7U3mPFAer4Q/yRnvWczyAiep0OFwXWamRA7T8dKdyewl7KS8F9FDs FEgY1BLQu2096pfgXgqTwm8hi2zkDjQ= X-MC-Unique: fkmscUJxPdq_ST0gwrOPtA-1 X-Mimecast-MFC-AGG-ID: fkmscUJxPdq_ST0gwrOPtA_1747815543 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747815542; x=1748420342; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DYNNR8kxdpigAzsfIWV54lNrAJSCQ81aFM7IBOhn2ic=; b=X+ve3XNoS0RkQbQXP0X1TzSBT3Z3qZFpncMNM3mXmVq1jr+vldaqaHiFaH8LwRVXUK fmiFq7AJ2q6lOj4pUNMZEMCuElk3uxp06hGikTSVGc9mm3PWBBlyh9G560V0cdSqo2fO d04YZ7rDKrnoZH96pK/AleVf5qp6HW4Xmuj+yDlq9J/d0zq39HM2WAOLiPnoDwIcyvw2 AR+pnqTQMV4BHURB4/mrrMOX0Rt+1RTpy3SMgEs4YEw71E/HY7NAWtPJIGv+ANQF+Pub I8+EEEn0oYxVR+GUA553hDC7Byo3HmjAYjaHzyKC91YiajzPSUM8Dnjxkwg643QHkfVA LaBw== X-Gm-Message-State: AOJu0YyUaD/uMm+NslizuV3Bsm9FVXFpTVVMLCnG9mkxGGGYDOHy5DWl T57KDnUMv+SmnaKUF+eMQSu+YH3CkOczgLm3XRJaVwX6DneA+fZQdu+DymLq9OfljD0w5UvRPY0 HAZvfvV8a3Z+9RhVsvRhM1yUdFvHivZAOFM5Gcmo4kf+44xZYlbzvVKDciP9LYA6xVVBvwEzSPY q4BWV31woSM5h8s3uMRGr0eb96AoYAjEDlErEUyCGF X-Gm-Gg: ASbGnctuRuq2ySd9fA4wdEiDuL5Q/XOyiii33LcQe8dnPNwZryyf5zUhkdEle3xQyOw 72eRKA/I0O8rD8AJzFORy7TECCpRVHWq+ghJ7EgxzXT4hhFzjkZmMgg6p+ghhikUXkK117Q2wi5 57nXaonteQSZWYCOocvxGRhd+VI1dlO4F3arrYu1+CpckzmYSyGjdPAXUaP3/QeASxpxx+L70z1 vI98IoWt81xgfgLBu/cTH5nJ8gQb9p8E+o5BQ2bdXM7G7ItWDWd7c13Myob+kvLcvT9qjHQheRu Z+awxm3WlC5cqQ== X-Received: by 2002:a05:6000:2912:b0:3a3:7cbd:39b1 with SMTP id ffacd0b85a97d-3a37cbd3a4amr3969548f8f.24.1747815542185; Wed, 21 May 2025 01:19:02 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGTv4UneDWAAT5256cTYhIwEYTuV/wYGAzeZOfqdtUiMDzLj9p2MCij0/aDKFQHgODH8wa6EQ== X-Received: by 2002:a05:6000:2912:b0:3a3:7cbd:39b1 with SMTP id ffacd0b85a97d-3a37cbd3a4amr3969500f8f.24.1747815541606; Wed, 21 May 2025 01:19:01 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, qemu-rust@nongnu.org, manos.pitsidianakis@linaro.org Subject: [RFC PATCH 6/6] rust: remove bilge crate Date: Wed, 21 May 2025 10:18:45 +0200 Message-ID: <20250521081845.496442-7-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250521081845.496442-1-pbonzini@redhat.com> References: <20250521081845.496442-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.487, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_FILL_THIS_FORM_SHORT=0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1747815634108116600 Content-Type: text/plain; charset="utf-8" Signed-off-by: Paolo Bonzini --- rust/Cargo.lock | 71 ++------------------- rust/qemu-api/src/vmstate.rs | 34 ++-------- subprojects/.gitignore | 7 -- subprojects/arbitrary-int-1-rs.wrap | 10 --- subprojects/bilge-0.2-rs.wrap | 10 --- subprojects/bilge-impl-0.2-rs.wrap | 10 --- subprojects/either-1-rs.wrap | 10 --- subprojects/itertools-0.11-rs.wrap | 10 --- subprojects/proc-macro-error-1-rs.wrap | 10 --- subprojects/proc-macro-error-attr-1-rs.wrap | 10 --- 10 files changed, 10 insertions(+), 172 deletions(-) delete mode 100644 subprojects/arbitrary-int-1-rs.wrap delete mode 100644 subprojects/bilge-0.2-rs.wrap delete mode 100644 subprojects/bilge-impl-0.2-rs.wrap delete mode 100644 subprojects/either-1-rs.wrap delete mode 100644 subprojects/itertools-0.11-rs.wrap delete mode 100644 subprojects/proc-macro-error-1-rs.wrap delete mode 100644 subprojects/proc-macro-error-attr-1-rs.wrap diff --git a/rust/Cargo.lock b/rust/Cargo.lock index bccfe855a70..29ac523bfdb 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -3,29 +3,11 @@ version =3D 3 =20 [[package]] -name =3D "arbitrary-int" -version =3D "1.2.7" +name =3D "bitfield-struct" +version =3D "0.9.5" source =3D "registry+https://github.com/rust-lang/crates.io-index" -checksum =3D "c84fc003e338a6f69fbd4f7fe9f92b535ff13e9af8997f3b14b6ddff8b1d= f46d" - -[[package]] -name =3D "bilge" -version =3D "0.2.0" -source =3D "registry+https://github.com/rust-lang/crates.io-index" -checksum =3D "dc707ed8ebf81de5cd6c7f48f54b4c8621760926cdf35a57000747c512e6= 7b57" +checksum =3D "b2869c63ccf4f8bf0d485070b880e60e097fb7aeea80ee82a0a94a957e37= 2a0b" dependencies =3D [ - "arbitrary-int", - "bilge-impl", -] - -[[package]] -name =3D "bilge-impl" -version =3D "0.2.0" -source =3D "registry+https://github.com/rust-lang/crates.io-index" -checksum =3D "feb11e002038ad243af39c2068c8a72bcf147acf05025dcdb916fcc000ad= b2d8" -dependencies =3D [ - "itertools", - "proc-macro-error", "proc-macro2", "quote", "syn", @@ -38,12 +20,6 @@ dependencies =3D [ "qemu_api_macros", ] =20 -[[package]] -name =3D "either" -version =3D "1.12.0" -source =3D "registry+https://github.com/rust-lang/crates.io-index" -checksum =3D "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385= b58b" - [[package]] name =3D "hpet" version =3D "0.1.0" @@ -52,15 +28,6 @@ dependencies =3D [ "qemu_api_macros", ] =20 -[[package]] -name =3D "itertools" -version =3D "0.11.0" -source =3D "registry+https://github.com/rust-lang/crates.io-index" -checksum =3D "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3= fe57" -dependencies =3D [ - "either", -] - [[package]] name =3D "libc" version =3D "0.2.162" @@ -71,36 +38,12 @@ checksum =3D "18d287de67fe55fd7e1581fe933d965a5a9477b38= e949cfa9f8574ef01506398" name =3D "pl011" version =3D "0.1.0" dependencies =3D [ - "bilge", - "bilge-impl", + "bitfield-struct", "bits", "qemu_api", "qemu_api_macros", ] =20 -[[package]] -name =3D "proc-macro-error" -version =3D "1.0.4" -source =3D "registry+https://github.com/rust-lang/crates.io-index" -checksum =3D "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5c= e38c" -dependencies =3D [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name =3D "proc-macro-error-attr" -version =3D "1.0.4" -source =3D "registry+https://github.com/rust-lang/crates.io-index" -checksum =3D "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35= f869" -dependencies =3D [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name =3D "proc-macro2" version =3D "1.0.84" @@ -152,9 +95,3 @@ name =3D "unicode-ident" version =3D "1.0.12" source =3D "registry+https://github.com/rust-lang/crates.io-index" checksum =3D "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0f= ee4b" - -[[package]] -name =3D "version_check" -version =3D "0.9.4" -source =3D "registry+https://github.com/rust-lang/crates.io-index" -checksum =3D "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e= 483f" diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 9c8b2398e9d..38faf6ce0dc 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -11,10 +11,9 @@ //! migration format for a struct. This is based on the [`VMState`] tra= it, //! which is defined by all migrateable types. //! -//! * [`impl_vmstate_forward`](crate::impl_vmstate_forward) and -//! [`impl_vmstate_bitsized`](crate::impl_vmstate_bitsized), which help = with -//! the definition of the [`VMState`] trait (respectively for transparent -//! structs and for `bilge`-defined types) +//! * [`impl_vmstate_forward`](crate::impl_vmstate_forward), which help wi= th the +//! definition of the [`VMState`] trait (respectively for transparent st= ructs +//! and for `bilge`-defined types) //! //! * helper macros to declare a device model state struct, in particular //! [`vmstate_subsections`](crate::vmstate_subsections) and @@ -141,7 +140,7 @@ macro_rules! info_enum_to_ref { /// The contents of this trait go straight into structs that are parsed by= C /// code and used to introspect into other structs. Generally, you don't = need /// to implement it except via macros that do it for you, such as -/// `impl_vmstate_bitsized!`. +/// `impl_vmstate_forward!`. pub unsafe trait VMState { /// The `info` member of a `VMStateField` is a pointer and as such can= not /// yet be included in the [`BASE`](VMState::BASE) associated constant; @@ -195,9 +194,8 @@ pub const fn vmstate_varray_flag(_: Phantom= Data) -> VMStateFlags /// * an array of any of the above /// /// In order to support other types, the trait `VMState` must be implement= ed -/// for them. The macros -/// [`impl_vmstate_bitsized!`](crate::impl_vmstate_bitsized) -/// and [`impl_vmstate_forward!`](crate::impl_vmstate_forward) help with t= his. +/// for them. The macro +/// [`impl_vmstate_forward!`](crate::impl_vmstate_forward) helps with this. #[macro_export] macro_rules! vmstate_of { ($struct_name:ty, $field_name:ident $([0 .. $num:ident $(* $factor:exp= r)?])? $(, $test_fn:expr)? $(,)?) =3D> { @@ -345,26 +343,6 @@ unsafe impl<$base> VMState for $type where $base: VMSt= ate $($where)* { impl_vmstate_transparent!(crate::cell::BqlRefCell where T: VMState); impl_vmstate_transparent!(crate::cell::Opaque where T: VMState); =20 -#[macro_export] -macro_rules! impl_vmstate_bitsized { - ($type:ty) =3D> { - unsafe impl $crate::vmstate::VMState for $type { - const SCALAR_TYPE: $crate::vmstate::VMStateFieldType =3D - <<<$type as ::bilge::prelude::Bits= ized>::ArbitraryInt - as ::bilge::prelude::Number>::Un= derlyingType - as $crate::vmstate::VMState>::SCA= LAR_TYPE; - const BASE: $crate::bindings::VMStateField =3D - <<<$type as ::bilge::prelude::Bits= ized>::ArbitraryInt - as ::bilge::prelude::Number>::Un= derlyingType - as $crate::vmstate::VMState>::BAS= E; - const VARRAY_FLAG: $crate::bindings::VMStateFlags =3D - <<<$type as ::bilge::prelude::Bits= ized>::ArbitraryInt - as ::bilge::prelude::Number>::Un= derlyingType - as $crate::vmstate::VMState>::VAR= RAY_FLAG; - } - }; -} - // Scalar types using predefined VMStateInfos =20 macro_rules! impl_vmstate_scalar { diff --git a/subprojects/.gitignore b/subprojects/.gitignore index 180c3134864..183700d986e 100644 --- a/subprojects/.gitignore +++ b/subprojects/.gitignore @@ -6,15 +6,8 @@ /keycodemapdb /libvfio-user /slirp -/arbitrary-int-1.2.7 -/bilge-0.2.0 -/bilge-impl-0.2.0 /bitfield-struct-0.9.5 -/either-1.12.0 -/itertools-0.11.0 /libc-0.2.162 -/proc-macro-error-1.0.4 -/proc-macro-error-attr-1.0.4 /proc-macro2-1.0.84 /quote-1.0.36 /syn-2.0.66 diff --git a/subprojects/arbitrary-int-1-rs.wrap b/subprojects/arbitrary-in= t-1-rs.wrap deleted file mode 100644 index a1838b20b0f..00000000000 --- a/subprojects/arbitrary-int-1-rs.wrap +++ /dev/null @@ -1,10 +0,0 @@ -[wrap-file] -directory =3D arbitrary-int-1.2.7 -source_url =3D https://crates.io/api/v1/crates/arbitrary-int/1.2.7/download -source_filename =3D arbitrary-int-1.2.7.tar.gz -source_hash =3D c84fc003e338a6f69fbd4f7fe9f92b535ff13e9af8997f3b14b6ddff8b= 1df46d -#method =3D cargo -patch_directory =3D arbitrary-int-1-rs - -# bump this version number on every change to meson.build or the patches: -# v2 diff --git a/subprojects/bilge-0.2-rs.wrap b/subprojects/bilge-0.2-rs.wrap deleted file mode 100644 index 900bb1497b9..00000000000 --- a/subprojects/bilge-0.2-rs.wrap +++ /dev/null @@ -1,10 +0,0 @@ -[wrap-file] -directory =3D bilge-0.2.0 -source_url =3D https://crates.io/api/v1/crates/bilge/0.2.0/download -source_filename =3D bilge-0.2.0.tar.gz -source_hash =3D dc707ed8ebf81de5cd6c7f48f54b4c8621760926cdf35a57000747c512= e67b57 -#method =3D cargo -patch_directory =3D bilge-0.2-rs - -# bump this version number on every change to meson.build or the patches: -# v2 diff --git a/subprojects/bilge-impl-0.2-rs.wrap b/subprojects/bilge-impl-0.= 2-rs.wrap deleted file mode 100644 index 4f84eca1ccd..00000000000 --- a/subprojects/bilge-impl-0.2-rs.wrap +++ /dev/null @@ -1,10 +0,0 @@ -[wrap-file] -directory =3D bilge-impl-0.2.0 -source_url =3D https://crates.io/api/v1/crates/bilge-impl/0.2.0/download -source_filename =3D bilge-impl-0.2.0.tar.gz -source_hash =3D feb11e002038ad243af39c2068c8a72bcf147acf05025dcdb916fcc000= adb2d8 -#method =3D cargo -patch_directory =3D bilge-impl-0.2-rs - -# bump this version number on every change to meson.build or the patches: -# v2 diff --git a/subprojects/either-1-rs.wrap b/subprojects/either-1-rs.wrap deleted file mode 100644 index 352e11cfee6..00000000000 --- a/subprojects/either-1-rs.wrap +++ /dev/null @@ -1,10 +0,0 @@ -[wrap-file] -directory =3D either-1.12.0 -source_url =3D https://crates.io/api/v1/crates/either/1.12.0/download -source_filename =3D either-1.12.0.tar.gz -source_hash =3D 3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb233= 85b58b -#method =3D cargo -patch_directory =3D either-1-rs - -# bump this version number on every change to meson.build or the patches: -# v2 diff --git a/subprojects/itertools-0.11-rs.wrap b/subprojects/itertools-0.1= 1-rs.wrap deleted file mode 100644 index ee12d0053bc..00000000000 --- a/subprojects/itertools-0.11-rs.wrap +++ /dev/null @@ -1,10 +0,0 @@ -[wrap-file] -directory =3D itertools-0.11.0 -source_url =3D https://crates.io/api/v1/crates/itertools/0.11.0/download -source_filename =3D itertools-0.11.0.tar.gz -source_hash =3D b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418= c3fe57 -#method =3D cargo -patch_directory =3D itertools-0.11-rs - -# bump this version number on every change to meson.build or the patches: -# v2 diff --git a/subprojects/proc-macro-error-1-rs.wrap b/subprojects/proc-macr= o-error-1-rs.wrap deleted file mode 100644 index 59f892f7825..00000000000 --- a/subprojects/proc-macro-error-1-rs.wrap +++ /dev/null @@ -1,10 +0,0 @@ -[wrap-file] -directory =3D proc-macro-error-1.0.4 -source_url =3D https://crates.io/api/v1/crates/proc-macro-error/1.0.4/down= load -source_filename =3D proc-macro-error-1.0.4.tar.gz -source_hash =3D da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a= 5ce38c -#method =3D cargo -patch_directory =3D proc-macro-error-1-rs - -# bump this version number on every change to meson.build or the patches: -# v2 diff --git a/subprojects/proc-macro-error-attr-1-rs.wrap b/subprojects/proc= -macro-error-attr-1-rs.wrap deleted file mode 100644 index 5aeb224a103..00000000000 --- a/subprojects/proc-macro-error-attr-1-rs.wrap +++ /dev/null @@ -1,10 +0,0 @@ -[wrap-file] -directory =3D proc-macro-error-attr-1.0.4 -source_url =3D https://crates.io/api/v1/crates/proc-macro-error-attr/1.0.4= /download -source_filename =3D proc-macro-error-attr-1.0.4.tar.gz -source_hash =3D a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b= 35f869 -#method =3D cargo -patch_directory =3D proc-macro-error-attr-1-rs - -# bump this version number on every change to meson.build or the patches: -# v2 --=20 2.49.0