From nobody Sun Dec 14 05:48:55 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=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1765082120; cv=none; d=zohomail.com; s=zohoarc; b=Ntzi/IckFuTr5O20PeVlKfkNaug588gBO3YgAeaL91kPHeJ8NIqTm+nRT8rZWNWRLuu+TFtOa5sqxPVLE1blv5M688vkyw4lMgk/XoqcyR5Onsxi4cjUUkg/mCjV1a/uJq0FbH3b3exAMsv0swsLgTWlZ4rGjcdRRunwsgJH2co= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1765082120; 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=TYQYrBtyfKJUAHag5BzfJ2Xcf0l0PHjigYu6ruxK0gU=; b=WagPITvUIP+mcXVLweN+Zfn5F5wEdihcNVwr5Ysu4KfIKRoMKM2zwrcx5MHKFc7/mHBVCiK74w6OI8kjE3pPqJF/tuxx4Lmkk2O7wkbIJbHLfmCGEHajWLdJUztsCnCdDs2LdgZC9ub3sL79NMAFOS/9oq7yZmsERxKIHwC5ctI= 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=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1765082120863100.59158593385439; Sat, 6 Dec 2025 20:35:20 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vS6TK-0001cP-Dn; Sat, 06 Dec 2025 23:34:10 -0500 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 1vS5XE-0002ul-69 for qemu-devel@nongnu.org; Sat, 06 Dec 2025 22:34:08 -0500 Received: from mail-pf1-x42f.google.com ([2607:f8b0:4864:20::42f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vS5X3-0002Tm-GB for qemu-devel@nongnu.org; Sat, 06 Dec 2025 22:34:01 -0500 Received: by mail-pf1-x42f.google.com with SMTP id d2e1a72fcca58-7b9c17dd591so3039402b3a.3 for ; Sat, 06 Dec 2025 19:33:49 -0800 (PST) Received: from nyaos.localdomain ([166.0.199.48]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6a1caeea7sm8496390a12.24.2025.12.06.19.33.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 Dec 2025 19:33:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1765078428; x=1765683228; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TYQYrBtyfKJUAHag5BzfJ2Xcf0l0PHjigYu6ruxK0gU=; b=mCqhMVgSYTupCxvSl0a2p1Bd65IKi1t3SGE+vKv3n1uZOohAIky8ZYGihrgE4N305h xzWW2bBvIYH8X0cBrQxsjcf3vWQmxLK+xHBiTKnAzyeLpSJKg0Xn4sAe+AsKU9Xqdd0v KZPBUGWQJaPw7WAxTjwKoWtlJ56RZjcaEn821o08niPlzaxokAqv7xDktWD9IAgfWWDw lomKfdZetRm83g1od+tSM/ay7Xvv8wx5MM6ep04ewO7xWj2eqRYn5mIb1iGIkcHK8smd 9Si0yk+eZ1DmcbJro6ptWaOMHShpoyTc4CElf6BO4+QDmFD2NBFtzql82XbsIT7aiUnn MbOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765078428; x=1765683228; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=TYQYrBtyfKJUAHag5BzfJ2Xcf0l0PHjigYu6ruxK0gU=; b=h/NdoOoMU5vfksgg55Nxgj1SkcashB3oX6y2gnt/xvkH0COI0xiskQxwZolhSypkf1 5w6wFDIxJUf/y2psd7qHLFgIXJVg39xmx2h1KRigB6Wun1FK42ZrDywJaIz9UE4Hdcbe vYvlaVyWf2TGP5WnlsKyDbobddGST7DHGCBzhpw57iL2ICoWgAnPrXTVsTRbbvMFeQHu zn3V+0p94UtCCQz1MoKJ9d99O7DnCNSXRi/Pt6umRVxqmNZWlpIkiqx9G5FCuEA5hs7k /totoMnZ/PNO4tqzVeEJ4cHc6rRtcF1ftfvgTymYj41uOpfFvl5/82rrBrMYWaasX+6+ HpVw== X-Forwarded-Encrypted: i=1; AJvYcCWbubH5G+ZsphBwMmuxQK0ZQ8hqZZUpbXQcrUaEItQLnUp5lS5Dm/B7enrtkUHN9p4fsR7HfyO5JPE+@nongnu.org X-Gm-Message-State: AOJu0Yywa5kL6jn6lb0dvD8LxjnS6uE97kEnF6WDVThaAUolp1+G9KKA YO+44zBYweWDJSzyih1mieafKuW+Q+k9aU8XsC/5WzYLxoqeSOrSvpKcU50aJtBc0JXGLQ== X-Gm-Gg: ASbGncuDbkUcrR7RuIN5uTXn4dPpueRgWX63OlAC+5oZ/pQqqDCduZEP1cqKLf9hqXQ Y2P96Vd59lQsvlrLugQtN33b9Vmmo4//oMirdcuATwAkdDXZp8/6GX1wzYIdiOcpRWZtVAnfEiv C1JXQNqYugJv1ku9Uiw6mOMUvLj7ZtA/hVCdLAnI8IIBibeRUS3wMIpSMmObTXKOQ11oyaVUefB QZ4GGcvGqobLW26Diwj+Xc7nsl+Dl1a3aTDDEt9Ywu6YTGNsbTxk5Wwhm2WXrSxXrgBQ0BqJdD5 GwSyFTiSzR9FBFv2QUUJt51L0fDzPzZfbCf4AHngJiq6aTY/YYKW7X7LwIBlAavqniNeE1OAc0K D76/vBMW1O4DTjoSP+sBdQA0f5muV6V1CgD5VqSCD+DT4E5TnwqBzQGQUg2gvw/4SQUk52zMGEI Mm+hVIxtISiZulVvd25KYUmppHhu+BmLIZVoMccPFY9pc6EA== X-Google-Smtp-Source: AGHT+IHLKeAyCUZ8NBnh10nkmhn9X2UWmYQZyZk1k2lI1Wod142J5tzz9PMYLXTZNInaffP16H73Cw== X-Received: by 2002:a05:6a21:32a0:b0:34f:4309:ed32 with SMTP id adf61e73a8af0-36617e6f4e5mr4032494637.23.1765078427849; Sat, 06 Dec 2025 19:33:47 -0800 (PST) From: ChenMiao To: zhao1.liu@intel.com, pbonzini@redhat.com, manos.pitsidianakis@linaro.org, richard.henderson@linaro.org, philmd@linaro.org Cc: chao.liu@openatom.club , dzm91@openatom.club , qemu-rust@nongnu.org, qemu-devel@nongnu.org, hust-os-kernel-patches@googlegroups.com, chenmiao Subject: [PATCH v3 1/4] rust/hw/core: Add the BusState of rust version Date: Sun, 7 Dec 2025 03:33:28 +0000 Message-ID: <4e3b8548a26867260f137c719d3c26a24d7954bd.1765077679.git.chenmiao@openatom.club> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: 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=2607:f8b0:4864:20::42f; envelope-from=chenmiao.ku@gmail.com; helo=mail-pf1-x42f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sat, 06 Dec 2025 23:34:09 -0500 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 @gmail.com) X-ZM-MESSAGEID: 1765082123281154100 Content-Type: text/plain; charset="utf-8" From: chenmiao A Rust version implementation has been designed for BusState, which will be used for the subsequent I2CBus implementation. Signed-off-by: Chen Miao Signed-off-by: Chao Liu --- rust/hw/core/meson.build | 1 + rust/hw/core/src/bus.rs | 44 ++++++++++++++++++++++++++++++++++++++++ rust/hw/core/src/lib.rs | 3 +++ 3 files changed, 48 insertions(+) create mode 100644 rust/hw/core/src/bus.rs diff --git a/rust/hw/core/meson.build b/rust/hw/core/meson.build index 1560dd20c6..efcda50fef 100644 --- a/rust/hw/core/meson.build +++ b/rust/hw/core/meson.build @@ -50,6 +50,7 @@ _hwcore_rs =3D static_library( [ 'src/lib.rs', 'src/bindings.rs', + 'src/bus.rs', 'src/irq.rs', 'src/qdev.rs', 'src/sysbus.rs', diff --git a/rust/hw/core/src/bus.rs b/rust/hw/core/src/bus.rs new file mode 100644 index 0000000000..d3fbf519d4 --- /dev/null +++ b/rust/hw/core/src/bus.rs @@ -0,0 +1,44 @@ +// Copyright 2025 HUST OpenAtom Open Source Club. +// Author(s): Chen Miao +// SPDX-License-Identifier: GPL-2.0-or-later + +use std::ffi::CStr; + +pub use bindings::BusClass; +use common::Opaque; +use qom::{qom_isa, IsA, Object, ObjectDeref, ObjectType}; + +use crate::{bindings, DeviceImpl}; + +#[repr(transparent)] +#[derive(Debug, common::Wrapper)] +pub struct BusState(Opaque); + +unsafe impl Send for BusState {} +unsafe impl Sync for BusState {} + +unsafe impl ObjectType for BusState { + type Class =3D BusClass; + const TYPE_NAME: &'static std::ffi::CStr =3D + unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_BUS) }; +} + +qom_isa!(BusState: Object); + +pub trait BusStateImpl: DeviceImpl + IsA {} + +impl BusClass { + pub fn class_init(self: &mut BusClass) { + self.parent_class.class_init::(); + } +} + +pub trait BusMethods: ObjectDeref +where + Self::Target: IsA, +{ + // TODO: Since the bus does not currently provide services to other + // components, we have not implemented any functions yet. +} + +impl BusMethods for R where R::Target: IsA {} diff --git a/rust/hw/core/src/lib.rs b/rust/hw/core/src/lib.rs index b40801eb84..10cc516664 100644 --- a/rust/hw/core/src/lib.rs +++ b/rust/hw/core/src/lib.rs @@ -13,3 +13,6 @@ =20 mod sysbus; pub use sysbus::*; + +mod bus; +pub use bus::*; --=20 2.43.0 From nobody Sun Dec 14 05:48:55 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=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1765082101; cv=none; d=zohomail.com; s=zohoarc; b=gNYoeH1/D+IJHAe4hxD7+FvLa793fxqH4+d+TxLlfmSVc3qEux+k3RHn3vzqKyOnPLY0vc3sX0J7bcF/xePV3CmCvvT9rLdvc8iduERLpkK4yPwwg0+r0/RnlZwjZRT6YFh+NljzFFtbpvt6PpnSYYTEJ/qM5A2FrwwAac+eDJs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1765082101; h=Content-Type: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=bSwW4pf421IMnpAOpJLVJ0KcWmgP1/il42L6E6pTLTg=; b=YGFzNCuCAcv1ySMmEi9BgkRUm+yymegcZEYz++uLLyRyjUtVmVspUqPh0AhcLCHEqq6ULZqTesw8txmduQ+bPOxTttve71MbSYHdkEXiL1psZWA6yi5nvw5Z6/eR+rCz4EkcjeX5Xz0DSLudWOFcT9+a9gUg8NIGhM6O96R9Udg= 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=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1765082101554789.9100061068327; Sat, 6 Dec 2025 20:35:01 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vS6TJ-0001bq-MH; Sat, 06 Dec 2025 23:34:09 -0500 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 1vS5XE-0002ud-3z for qemu-devel@nongnu.org; Sat, 06 Dec 2025 22:34:08 -0500 Received: from mail-pf1-x429.google.com ([2607:f8b0:4864:20::429]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vS5X3-0002UA-G5 for qemu-devel@nongnu.org; Sat, 06 Dec 2025 22:34:01 -0500 Received: by mail-pf1-x429.google.com with SMTP id d2e1a72fcca58-7bf0ad0cb87so3872815b3a.2 for ; Sat, 06 Dec 2025 19:33:54 -0800 (PST) Received: from nyaos.localdomain ([166.0.199.48]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6a1caeea7sm8496390a12.24.2025.12.06.19.33.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 Dec 2025 19:33:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1765078434; x=1765683234; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=bSwW4pf421IMnpAOpJLVJ0KcWmgP1/il42L6E6pTLTg=; b=lfk/kXqyt2qp1s0BYp+e2MqVmcSAWKWAhoujvaPgkECJ3UmGkr08VxqOP124OInYn4 NSLid2pNyOgQxfpymzjv+GinyPtPuVN48ypAgcIS+U6ZJVjvindIlO98u1EejLQu6YB/ DkLWidBjZ/P2WlQTmr5RDcvRCXIIvkpi68z8Ky4nirnqIpFK9VlNSQybDF7arPLP1ZrH Ei8VN5nDDuevsSIWL5QKCfIeZvPD9wo6tRTpZ72t5G6vcUFui5z6e9qmpOwJoNMM7mBo 1Xya132/Qbh5FEAt1YCR0y3WmD142add+7huTRvSqGkWDLilwfM5IG4bUXFV7Duy3xUv EXPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765078434; x=1765683234; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=bSwW4pf421IMnpAOpJLVJ0KcWmgP1/il42L6E6pTLTg=; b=w2WeCShcl/1QTm271Chle9qoH5On6DCx+Kc3KnB94VwyEMMiV3cQd7ylj7e1HBZdBw YspPDSh1+5hzUM0jWhj5iHwSTVl9YNdOnlAospeKNANC/vrBnoKQyGEjc/3jVKOM3gwR w8GCm0X5lvvOvdlZY9XNuRiKEKC8ybXgJgPrGgGxXBoDBkm956tayJMB4grGglRBGOZi IE/P+UTCW9etHa8guos1DuD33Do/y6nSUyLWm4XkakjmT3wnfYIMEfKeM6pbU3Er5Q0D fT3yBUEXG3a4YDEAZAM0kmGDJnOC0NNsm/FeOnI+rPotIZl8gvtJBGeNioIxtR/A5ri4 HJxQ== X-Forwarded-Encrypted: i=1; AJvYcCVQ7Ga93Pvqrpvwudw0mDoE8mCRMVPnQ1IuscIT8fJDTBvAikwqHhe4pxwb9W7M1CGSwrIbis06vAbG@nongnu.org X-Gm-Message-State: AOJu0Yxt6WJL60LxBuq+7EVvcvq9tWIgcFzzjLI5RQ1FKhhYt34wLlNr SGK7kUASoHP2bo7b0o8mIa0bvp59wzivMSd25EEGSymX0E5rTZusKbjj X-Gm-Gg: ASbGncsGvGUeooKUkfNFRokVp14zjoQ47lBvlWL6my5ziihRJzBnMUHgQ8XICiIDtEg i1iO1/X7Xfsl5qisouAuPH/TrQZhx0Uq/y7BGcGkTzYDVUMyUG1/QwYdnymWTre4dRxnxm8vf+D GwqXiy8VvwUMF0rfrkW7kCC6o4Rcj8Yq+Eh4/9FUPNo8f8e0xKmwpycrKpNHHHxZ1SNdqUVqH2o 0Z78O0yBf5PCekncGM1/YhNTEcUZXsZlg/XpP/P3bmFo4gDjBLnTlsC0a/wNIolfoiTHGlDq0FL YwfAiUtrgCpFc+R+lguh3eKoWPR9RyQf3Kqr1vRL6bXdeDw1VYXJyB4KI7nRRmD2z9duWDlxczb s7cLiDT+sn3WhzoUVNHoiWtJZybJZ8yNDxl6H5imdZX8CY1GI2ZCU14yRB0fJWY3DfQNgbJqsfA YfDVOe+Dy3e4K849mtacQFt2Sjaa4B0oj5em455IEaJq8YaVK+e+4xxXNX X-Google-Smtp-Source: AGHT+IHpR8p/qL9farnjOh8NgbA99bpbxfluk9KjHutTIiDbXkCzieunD6uKWtl0YXYZKJ4dl6FHGg== X-Received: by 2002:a05:6a21:4ed7:20b0:366:14ac:e1de with SMTP id adf61e73a8af0-3661802629amr2693628637.68.1765078433718; Sat, 06 Dec 2025 19:33:53 -0800 (PST) From: ChenMiao To: zhao1.liu@intel.com, pbonzini@redhat.com, manos.pitsidianakis@linaro.org, richard.henderson@linaro.org, philmd@linaro.org Cc: chao.liu@openatom.club , dzm91@openatom.club , qemu-rust@nongnu.org, qemu-devel@nongnu.org, hust-os-kernel-patches@googlegroups.com, chenmiao Subject: [PATCH v3 2/4] rust/hw/core: Add rust bindings/funcs for i2c bus Date: Sun, 7 Dec 2025 03:33:29 +0000 Message-ID: <48bfe2bd3b11f09bd501622370ca64bdb1f68afb.1765077679.git.chenmiao@openatom.club> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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=2607:f8b0:4864:20::429; envelope-from=chenmiao.ku@gmail.com; helo=mail-pf1-x429.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sat, 06 Dec 2025 23:34:06 -0500 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 @gmail.com) X-ZM-MESSAGEID: 1765082103546154100 From: chenmiao We have implemented the I2CBus and I2CSlave infrastructure in Rust by refer= ring to the SysBus device model. Initially, we assumed that the I2CBus was at the same hierarchical level as= the PL011 device. Therefore, we followed the implementation paradigm of the PL0= 11 device as a reference. However, in the end, we discovered that the I2CBus is actually at the same level as the SysBus. As a result, we adopted the bindi= ng implementation paradigm used for SysBus devices. With this adjustment, we successfully compiled the code locally. During the implementation process, we found that the current two paradigms = in Rust =E2=80=94 bindings and impl =E2=80=94 are extremely complex and lack c= omprehensive documentation. There is no clear explanation as to why Bus and Device models need to be implemented using different approaches. Furthermore, the implementation of Bus and Device following these paradigms still has many limitations. At present, at least vmstate is not easily supported. Signed-off-by: Chao Liu Signed-off-by: Chen Miao --- rust/hw/core/meson.build | 1 + rust/hw/core/src/i2c.rs | 303 +++++++++++++++++++++++++++++++++++++++ rust/hw/core/src/lib.rs | 3 + rust/hw/core/wrapper.h | 1 + 4 files changed, 308 insertions(+) create mode 100644 rust/hw/core/src/i2c.rs diff --git a/rust/hw/core/meson.build b/rust/hw/core/meson.build index efcda50fef..1a27c1cff7 100644 --- a/rust/hw/core/meson.build +++ b/rust/hw/core/meson.build @@ -52,6 +52,7 @@ _hwcore_rs =3D static_library( 'src/bindings.rs', 'src/bus.rs', 'src/irq.rs', + 'src/i2c.rs', 'src/qdev.rs', 'src/sysbus.rs', ], diff --git a/rust/hw/core/src/i2c.rs b/rust/hw/core/src/i2c.rs new file mode 100644 index 0000000000..85ec34357a --- /dev/null +++ b/rust/hw/core/src/i2c.rs @@ -0,0 +1,303 @@ +// Copyright 2025 HUST OpenAtom Open Source Club. +// Author(s): Chao Liu +// Author(s): Chen Miao +// SPDX-License-Identifier: GPL-2.0-or-later + +//! Bindings to access `i2c` functionality from Rust. + +use std::{ffi::CStr, ptr::NonNull}; + +pub use crate::bindings::I2CSlaveClass; +use common::{self, Opaque}; +use migration::impl_vmstate_c_struct; +use qom::{prelude::*, Owned}; + +use crate::{ + bindings, + bus::{BusClass, BusState}, + qdev::{DeviceImpl, DeviceState}, +}; + +/// A safe wrapper around [`bindings::I2CBus`]. +#[repr(transparent)] +#[derive(Debug, common::Wrapper)] +pub struct I2CBus(Opaque); + +unsafe impl Send for I2CBus {} +unsafe impl Sync for I2CBus {} + +unsafe impl ObjectType for I2CBus { + type Class =3D BusClass; + const TYPE_NAME: &'static CStr =3D + unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_I2C_BU= S) }; +} + +qom_isa!(I2CBus: BusState, Object); + +/// Trait for methods of [`I2CBus`] and its subclasses. +pub trait I2CBusMethods: ObjectDeref +where + Self::Target: IsA, +{ + /// # Safety + /// + /// Initialize an I2C bus + fn init_bus(&self, parent: &DeviceState, name: &str) -> Owned { + assert!(bql::is_locked()); + unsafe { + let bus =3D bindings::i2c_init_bus(parent.as_mut_ptr(), name.a= s_ptr().cast()); + let bus: &I2CBus =3D I2CBus::from_raw(bus); + Owned::from(bus) + } + } + + /// # Safety + /// + /// Start a transfer on an I2C bus + fn start_transfer(&self, address: u8, is_recv: bool) -> i32 { + assert!(bql::is_locked()); + unsafe { bindings::i2c_start_transfer(self.upcast().as_mut_ptr(), = address, is_recv) } + } + + /// # Safety + /// + /// Start a receive transfer on an I2C bus + fn start_recv(&self, address: u8) -> i32 { + assert!(bql::is_locked()); + unsafe { bindings::i2c_start_recv(self.upcast().as_mut_ptr(), addr= ess) } + } + + /// # Safety + /// + /// Start a send transfer on an I2C bus + fn start_send(&self, address: u8) -> i32 { + assert!(bql::is_locked()); + unsafe { bindings::i2c_start_send(self.upcast().as_mut_ptr(), addr= ess) } + } + + /// # Safety + /// + /// End a transfer on an I2C bus + fn end_transfer(&self) { + assert!(bql::is_locked()); + unsafe { bindings::i2c_end_transfer(self.upcast().as_mut_ptr()) } + } + + /// # Safety + /// + /// Send NACK on an I2C bus + fn nack(&self) { + assert!(bql::is_locked()); + unsafe { bindings::i2c_nack(self.upcast().as_mut_ptr()) } + } + + /// # Safety + /// + /// Send ACK on an I2C bus + fn ack(&self) { + assert!(bql::is_locked()); + unsafe { bindings::i2c_ack(self.upcast().as_mut_ptr()) } + } + + /// # Safety + /// + /// Send data on an I2C bus + fn send(&self, data: u8) -> i32 { + assert!(bql::is_locked()); + unsafe { bindings::i2c_send(self.upcast().as_mut_ptr(), data) } + } + + /// # Safety + /// + /// Receive data from an I2C bus + fn recv(&self) -> u8 { + assert!(bql::is_locked()); + unsafe { bindings::i2c_recv(self.upcast().as_mut_ptr()) } + } + + /// # Safety + /// + /// Check if the I2C bus is busy. + /// + /// Returns `true` if the bus is busy, `false` otherwise. + fn is_busy(&self) -> bool { + assert!(bql::is_locked()); + unsafe { bindings::i2c_bus_busy(self.upcast().as_mut_ptr()) !=3D 0= } + } + + /// # Safety + /// + /// Schedule pending master on an I2C bus + fn schedule_pending_master(&self) { + assert!(bql::is_locked()); + unsafe { bindings::i2c_schedule_pending_master(self.upcast().as_mu= t_ptr()) } + } + + /// Sets the I2C bus master. + /// + /// # Safety + /// + /// This function is unsafe because: + /// - `bh` must be a valid pointer to a `QEMUBH`. + /// - The caller must ensure that `self` is in a valid state. + /// - The caller must guarantee no data races occur during execution. + /// + /// TODO ("`i2c_bus_master` missing until QEMUBH is wrapped") + unsafe fn set_master(&self, bh: *mut bindings::QEMUBH) { + assert!(bql::is_locked()); + unsafe { bindings::i2c_bus_master(self.upcast().as_mut_ptr(), bh) } + } +} + +impl I2CBusMethods for R where R::Target: IsA {} + +/// A safe wrapper around [`bindings::I2CSlave`]. +#[repr(transparent)] +#[derive(Debug, common::Wrapper)] +pub struct I2CSlave(Opaque); + +unsafe impl Send for I2CSlave {} +unsafe impl Sync for I2CSlave {} + +unsafe impl ObjectType for I2CSlave { + type Class =3D I2CSlaveClass; + const TYPE_NAME: &'static CStr =3D + unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_I2C_SL= AVE) }; +} + +qom_isa!(I2CSlave: DeviceState, Object); + +impl_vmstate_c_struct!(I2CSlave, bindings::vmstate_i2c_slave); + +#[derive(common::TryInto)] +#[repr(u64)] +#[allow(non_camel_case_types)] +pub enum I2CResult { + ACK =3D 0, + NACK =3D 1, +} + +// TODO: add virtual methods +pub trait I2CSlaveImpl: DeviceImpl + IsA { + /// Master to slave. Returns non-zero for a NAK, 0 for success. + const SEND: Option I2CResult> =3D None; + + /// Slave to master. This cannot fail, the device should always return= something here. + const RECV: Option u8> =3D None; + + /// Notify the slave of a bus state change. For start event, + /// returns non-zero to NAK an operation. For other events the + /// return code is not used and should be zero. + const EVENT: Option I2CEvent> =3D None; + + /// Check if this device matches the address provided. Returns bool of + /// true if it matches (or broadcast), and updates the device list, fa= lse + /// otherwise. + /// + /// If broadcast is true, match should add the device and return true. + #[allow(clippy::type_complexity)] + const MATCH_AND_ADD: Option< + fn(&Self, address: u8, broadcast: bool, current_devs: *mut binding= s::I2CNodeList) -> bool, + > =3D None; +} + +/// # Safety +/// +/// We expect the FFI user of this function to pass a valid pointer that +/// can be downcasted to type `T`. We also expect the device is +/// readable/writeable from one thread at any time. +unsafe extern "C" fn rust_i2c_slave_send_fn( + obj: *mut bindings::I2CSlave, + data: u8, +) -> std::os::raw::c_int { + let state =3D NonNull::new(obj).unwrap().cast::(); + T::SEND.unwrap()(unsafe { state.as_ref() }, data).into_bits() as std::= os::raw::c_int +} + +/// # Safety +/// +/// We expect the FFI user of this function to pass a valid pointer that +/// can be downcasted to type `T`. We also expect the device is +/// readable/writeable from one thread at any time. +unsafe extern "C" fn rust_i2c_slave_recv_fn(obj: *mut bin= dings::I2CSlave) -> u8 { + let state =3D NonNull::new(obj).unwrap().cast::(); + T::RECV.unwrap()(unsafe { state.as_ref() }) +} + +/// # Safety +/// +/// We expect the FFI user of this function to pass a valid pointer that +/// can be downcasted to type `T`. We also expect the device is +/// readable/writeable from one thread at any time. +unsafe extern "C" fn rust_i2c_slave_event_fn( + obj: *mut bindings::I2CSlave, + event: bindings::i2c_event, +) -> std::os::raw::c_int { + let state =3D NonNull::new(obj).unwrap().cast::(); + T::EVENT.unwrap()(unsafe { state.as_ref() }, I2CEvent::from_bits(event= )).into_bits() + as std::os::raw::c_int +} + +/// # Safety +/// +/// We expect the FFI user of this function to pass a valid pointer that +/// can be downcasted to type `T`. We also expect the device is +/// readable/writeable from one thread at any time. +unsafe extern "C" fn rust_i2c_slave_match_and_add_fn( + obj: *mut bindings::I2CSlave, + address: u8, + broadcast: bool, + current_devs: *mut bindings::I2CNodeList, +) -> bool { + let state =3D NonNull::new(obj).unwrap().cast::(); + T::MATCH_AND_ADD.unwrap()(unsafe { state.as_ref() }, address, broadcas= t, current_devs) +} + +impl I2CSlaveClass { + /// Fill in the virtual methods of `I2CSlaveClass` based on the + /// definitions in the `I2CSlaveImpl` trait. + pub fn class_init(&mut self) { + if ::SEND.is_some() { + self.send =3D Some(rust_i2c_slave_send_fn::); + } + if ::RECV.is_some() { + self.recv =3D Some(rust_i2c_slave_recv_fn::); + } + if ::EVENT.is_some() { + self.event =3D Some(rust_i2c_slave_event_fn::); + } + if ::MATCH_AND_ADD.is_some() { + self.match_and_add =3D Some(rust_i2c_slave_match_and_add_fn::<= T>); + } + self.parent_class.class_init::(); + } +} + +/// Trait for methods of [`I2CSlave`] and its subclasses. +pub trait I2CSlaveMethods: ObjectDeref +where + Self::Target: IsA, +{ + /// Get the I2C bus address of a slave device + fn get_address(&self) -> u8 { + assert!(bql::is_locked()); + // SAFETY: the BQL ensures that no one else writes to the I2CSlave= structure, + // and the I2CSlave must be initialized to get an IsA. + let slave =3D unsafe { *self.upcast().as_ptr() }; + slave.address + } +} + +impl I2CSlaveMethods for R where R::Target: IsA = {} + +/// Enum representing I2C events +#[derive(common::TryInto)] +#[repr(u32)] +#[allow(non_camel_case_types)] +pub enum I2CEvent { + START_RECV =3D bindings::I2C_START_RECV, + START_SEND =3D bindings::I2C_START_SEND, + START_SEND_ASYNC =3D bindings::I2C_START_SEND_ASYNC, + FINISH =3D bindings::I2C_FINISH, + NACK =3D bindings::I2C_NACK, +} diff --git a/rust/hw/core/src/lib.rs b/rust/hw/core/src/lib.rs index 10cc516664..3f3aecb258 100644 --- a/rust/hw/core/src/lib.rs +++ b/rust/hw/core/src/lib.rs @@ -16,3 +16,6 @@ =20 mod bus; pub use bus::*; + +mod i2c; +pub use i2c::*; diff --git a/rust/hw/core/wrapper.h b/rust/hw/core/wrapper.h index 3bdbd1249e..399be594da 100644 --- a/rust/hw/core/wrapper.h +++ b/rust/hw/core/wrapper.h @@ -30,3 +30,4 @@ typedef enum memory_order { #include "hw/qdev-properties.h" #include "hw/qdev-properties-system.h" #include "hw/irq.h" +#include "hw/i2c/i2c.h" --=20 2.43.0 From nobody Sun Dec 14 05:48:55 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=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1765082116; cv=none; d=zohomail.com; s=zohoarc; b=Evgl9D1JiaFyjq7h9xCbV1M/DA79WxyWr7Q0TbgHvGrsE6wnj6XB4QJr70tootB1khkhmyV8KNzIf0qhe+U4z1Jll1RM5dYreSG7cf1bjrFnWH5/n7kkVyBOhKwmmt1Jp7KkuUAUZfNyzL3synBZw+EtynqYH9pCcnTQuQWTygw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1765082116; 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=Q7GAq65ALZiNekqSL+tWMcLPurYu/ToQPTuazfohejU=; b=mxvfRDCNWxUUVQGruIYGYdbWKxyvDrrgA10tzKgZ0HJOUOMbdXFV0TT4HPDvossD6YVmdyBmralix+eCvapdjr35VS50cIl+Ap/MXs+1te0/+3gq6gKWdbJBukOIfwUNIk0+PzfUVqru3elLYRfYx1nwlPSFcLsFUsjaFMYxb34= 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=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1765082116058581.864678336493; Sat, 6 Dec 2025 20:35:16 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vS6TO-0001cg-Bp; Sat, 06 Dec 2025 23:34:14 -0500 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 1vS5XF-0002vB-A2 for qemu-devel@nongnu.org; Sat, 06 Dec 2025 22:34:10 -0500 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vS5XD-0002V2-RA for qemu-devel@nongnu.org; Sat, 06 Dec 2025 22:34:09 -0500 Received: by mail-pf1-x435.google.com with SMTP id d2e1a72fcca58-7c66822dd6dso2864113b3a.0 for ; Sat, 06 Dec 2025 19:34:01 -0800 (PST) Received: from nyaos.localdomain ([166.0.199.48]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6a1caeea7sm8496390a12.24.2025.12.06.19.33.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 Dec 2025 19:33:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1765078440; x=1765683240; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Q7GAq65ALZiNekqSL+tWMcLPurYu/ToQPTuazfohejU=; b=XExwoL2bUodm/KVVocRHND8dtxbUNz4CTo9oC9H9+OnyKzyzRhdxwWwCp7bFoa5ok9 yuxcBuns+4SOShIxHasBMvhKa3z5bAh/RLsT+bWU7/qRWMxbryAWDKAso0UZMJN4A6Fd IA5pvDjhlV6Bmdk6Q35fWXs5n5VBkOYAhnoUtJW1fa+dBFvcosibjEE/14MH2yVLgcfm SAC2MnFwROKqUbfIibMfim37Ngxn0YZOSg4JnENWx/vSGSsI2WzMl23ebQi/+DJ4/g+5 ZkW/oE8eDSLfmSqXQ2jhaDC8zg6+Uj2K+lknz5vTMmC2s0a9ctXqTIrPqoIk8pzcZELk kebQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765078440; x=1765683240; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Q7GAq65ALZiNekqSL+tWMcLPurYu/ToQPTuazfohejU=; b=uVN+MieeP4Brjomt5flj1W8sONS/kIhv1BudQpEN1C6Jb8Eiwe5BpQ6LRA+dys3/Ht zchPdlMrt55Q3uCjLXBBhUVOGXqq/ctfm2KNhVq4xfIn6ParvPaUn114TvLjCusit+hK qPmucZtPUysUp0B+8q+hpPePiXpqZ3lME1GuxhFu/7KAOygv/rBhU9lrqZ+ZzpFqA7MU +X0cIK1xvYmVK4Q5DR9JftqLmqe3nXMzqTTbqjXUSWEkkd8JXvoLlK1OmF2tcKv3K5dC SsYHcHPrkivcKy6XtDVQfmv6Tm0sUgVMhZNnJmTcKgSrNemSqAXgz5Ak7ARTH8XjQk0n fUOw== X-Forwarded-Encrypted: i=1; AJvYcCXyxPqd4dHxrflqTa0vjwyJKRzHntwUJzSmEh1bKtQ6ypn+ThvHqwMekLzJCBw4NPeEZhfVGYPvb3Bs@nongnu.org X-Gm-Message-State: AOJu0YzWuJK93RXFuz181NxMlqP7PvQTnPyo+QxKWriMyP1380f+KyKM b0M6SzPSpQv3worZO1C/gNLD3c20V+k+9W9ftClYk2ZN1uh3zNDRZjQa X-Gm-Gg: ASbGncuhiYCOud2GEF+nuLRZhwVLD82QZuYP54qDp4WYDhLjJaNZJpZxBI5m0zunKo7 LNPsoSAmCvBHvNlVyi+/yFrEDpg6YoPlAnZ0otUqCaZmuoijFWmlW4Ac6uktEuyV+4pWIxhIjWN PTa4rJYzS6ABtHwYMDw6i+VfIzaTKHaO4PPduriy+Wv12YP6SX+mR6ImIueH71VkHDqyjhSDoRi /hPv9eStettPZyhJOVVCjsAhIuCMsyboGddSS7ib22PHOVJsfkCZokGh9EDIrhF6r0dY8/F0dMO z5I3VgKQafCKGPIUemVI+hfpZbh+mJz9NycvQEmIWr/RKIS7Upu/v6hjSa7IIToEjcy8biaTfBC 616EdjcAFxEkLRciitCefAtfBPlNqBD4zazvBWgmkkcf8BbXJQVWpGiGkAhnZrtBXh+yLcbGIYL /ZcReSxmGjNVUG1s3MHGQ4n6LZf2DP1694RDCWmAsOewnQpA== X-Google-Smtp-Source: AGHT+IEMK4FwfiNE8kVKS6xJzAqj8hag2Nxs8wAx3qBd4ELvbUbobC30vgtbjXKA+Mvb59QCehGXBw== X-Received: by 2002:a05:6a20:3950:b0:35f:4e9d:d280 with SMTP id adf61e73a8af0-36403343f9dmr12510286637.19.1765078440469; Sat, 06 Dec 2025 19:34:00 -0800 (PST) From: ChenMiao To: zhao1.liu@intel.com, pbonzini@redhat.com, manos.pitsidianakis@linaro.org, richard.henderson@linaro.org, philmd@linaro.org Cc: chao.liu@openatom.club , dzm91@openatom.club , qemu-rust@nongnu.org, qemu-devel@nongnu.org, hust-os-kernel-patches@googlegroups.com, chenmiao Subject: [PATCH v3 3/4] rust/hw/core: Provide some interfaces for the GPIO device Date: Sun, 7 Dec 2025 03:33:30 +0000 Message-ID: <69e22b6002d411a8edee3f589c568ce8217c2f37.1765077679.git.chenmiao@openatom.club> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: 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=2607:f8b0:4864:20::435; envelope-from=chenmiao.ku@gmail.com; helo=mail-pf1-x435.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sat, 06 Dec 2025 23:34:12 -0500 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 @gmail.com) X-ZM-MESSAGEID: 1765082119376154100 Content-Type: text/plain; charset="utf-8" From: chenmiao In qdev.rs, we implemented the init_gpio_out_named function, which correspo= nds to the C function qdev_init_gpio_out_named. We also refactored the init_gpio_out function to reuse the init_gpio_out_named interface. Signed-off-by: Chen Miao --- rust/hw/core/src/qdev.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/rust/hw/core/src/qdev.rs b/rust/hw/core/src/qdev.rs index c3097a284d..28da94dd0a 100644 --- a/rust/hw/core/src/qdev.rs +++ b/rust/hw/core/src/qdev.rs @@ -17,7 +17,7 @@ =20 pub use crate::bindings::{ClockEvent, DeviceClass, Property, ResetType}; use crate::{ - bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, ResettableClas= s}, + bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out_named, Resettab= leClass}, irq::InterruptSource, }; =20 @@ -399,11 +399,22 @@ fn do_init_gpio_in( } =20 fn init_gpio_out(&self, pins: &[InterruptSource]) { + self.init_gpio_out_named(pins, "unnamed-gpio-out", pins.len()); + } + + fn init_gpio_out_named(&self, pins: &[InterruptSource], name: &str, n:= usize) { + let c_name =3D if name.is_empty() { + CString::new("unnamed-gpio-out").unwrap() + } else { + CString::new(name).unwrap() + }; + unsafe { - qdev_init_gpio_out( + qdev_init_gpio_out_named( self.upcast().as_mut_ptr(), InterruptSource::slice_as_ptr(pins), - pins.len() as c_int, + c_name.as_ptr(), + n as c_int, ); } } --=20 2.43.0 From nobody Sun Dec 14 05:48:55 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=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1765082085; cv=none; d=zohomail.com; s=zohoarc; b=gDt6CqRhNNv8jYtGUskmLVy1HTbLNtkIYgoI4aJDew+Mxdo8y5kZ6ukVBtAbTZrU3d8rT1JgCg2uDlxl5CkjfJtE5Mw6iK5Z3x0NrPy/4j7nmvZxyU8SpzarghvjqeaWmPp+G52AmT75y6lTslsEH9F4IoTVp5nBW/0oR725p9o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1765082085; h=Content-Type: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=ZxHzwdNs0hmfF7X9ON6zGAVj61NHy2UgBo4Qhmy9qRg=; b=hKrcVLNYOU1E5IPwkfjK/htSKIqPX0wbcDwi9x6qqmWdXm+LVopHqeUtPVaGLUm6n8NEvWns7ap/MKBoJAokGAFwtEDs7biolPFpzXHltxSQKaPlhSAaOdFwn2lDFkTrNG19nArFiyYs/Q2pXNUwlWU8QDaWE1wg0XTR2b9xcf8= 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=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1765082085237795.8303735090055; Sat, 6 Dec 2025 20:34:45 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vS6TN-0001cd-U6; Sat, 06 Dec 2025 23:34:13 -0500 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 1vS5XI-0002wK-2e for qemu-devel@nongnu.org; Sat, 06 Dec 2025 22:34:12 -0500 Received: from mail-pf1-x42d.google.com ([2607:f8b0:4864:20::42d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vS5XD-0002VU-S9 for qemu-devel@nongnu.org; Sat, 06 Dec 2025 22:34:10 -0500 Received: by mail-pf1-x42d.google.com with SMTP id d2e1a72fcca58-7baf61be569so3891635b3a.3 for ; Sat, 06 Dec 2025 19:34:07 -0800 (PST) Received: from nyaos.localdomain ([166.0.199.48]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6a1caeea7sm8496390a12.24.2025.12.06.19.34.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 Dec 2025 19:34:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1765078446; x=1765683246; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZxHzwdNs0hmfF7X9ON6zGAVj61NHy2UgBo4Qhmy9qRg=; b=Xktd5gAVgq8tvF7aEBf4s783dstXV1e1WDayGZRaEYxCxyRrMKCut7w6BToK4nSd6n Q/Hn1HhMTTXBydTQI8Eg5h3p1A6wSqSOSXxDn5WBvUBfmmtTVfGX28xDCaQxOB0QwK7t +RcunEeWhDm3HKrWltaMH9EyzzLMdIE5Kf4w3duJxc/UcpJnqem8nZ0xC1FNfzDZY/xp x+apGb4l0UhXlyiUVbOQqXrL2ztuXFr+YSGyt9F/rGcTEEH55vD1N1XOwAuC9zvSPYYO FJ2GPnzapqPIjnePPXE4KYzVV2nCKA+C3dw/kc4cEtP6EC6setmhBVjrSFjaDRgGLczZ 0LEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765078446; x=1765683246; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ZxHzwdNs0hmfF7X9ON6zGAVj61NHy2UgBo4Qhmy9qRg=; b=YwaLgIIl6Vhv4+8hPwbiX6h48FG82mFqtjLNd41OKLvGFg1Z8lt2lbJcUsrnDRATVQ hNZpgsb1hxb25497VT/Fl7HmO2PSp/Uyy8W9LeRYYDpc4UWCBdnZaHJ7kF4Y9II2gxO8 AHb0s7szFs4Px1tbupqTS8eRxfp+ptyqC7U9UZ5VyFPrzBPEIhQyPjXv32mBdqhhbRbA pRhN2iKQHs//nGIJEbUD5ihJdoqEjWKdm73ng6RlZYt4xiv7wL8XlID1UKeKY0KoZ578 XgnJHX0NrJ0ypN2Tb+Vzv0W4Miq5s41N0A22Ujg+Us0MjaEfjasitbGeiIRRpoqw+rx0 0u8w== X-Forwarded-Encrypted: i=1; AJvYcCWXZtxQUR3RVHk12JIsSK092DyG8Q/k2K7IpV8WMZrNs9ompXSCEp/ULGeSz7Ym1oErjpKLdygojOZA@nongnu.org X-Gm-Message-State: AOJu0YxBOnwkLMR93zs+CkfXMjvJiGEKYJrXjjZ8ZOBvl4xQX8GRfJOI dRD2YsfEekXnbGfhpnz8FAj+CjVwKpyLRRk1jjI/JP7f5LifwV0nDrI2 X-Gm-Gg: ASbGnctlrx526uymf4fAZXr+yEL1LhCLdHfwFfFyNLT4uvDuqiyViIO9YBuv4SWKBRT LEz9vDTVxl4c7gxLMX3fEitVruDV79RB+8sdeyyxK667deExaw0dglWRVtBGJFcTt81G0RxlY11 rj+r8vhO4BnDRlwnsFtEbTzVnZCvrW4c1hrsnkFRbIVRpPahfb19rGXXIFlbTKRod4XoGoQPBxb 5OcV0nPDpDDUlPpPjR9tQvk+B6yowDpu96aJQP3eg20+axYYo82FQk20jpPNGdM4c/2QvXI87fU BHyAJG5ZeSUtl2u83Hu5MHzkiV+4aaTW2UzlCQ4XeKg//BJv7qbWHx/jcpsmwLtdMQd/BL8pQ0O XIcIMpNM7D7nUUZsY9zN/0DkE8V3k3Bk+WpyBr85woHAuBDOpjoNooqopEFhBzilYZvFLb9VmPC KzzfcgkwSxeKryhq8kwClNFDcFSfBdgNx/AsYUCFdPVvs4Nw== X-Google-Smtp-Source: AGHT+IEGdl4AcEdp6fnOnIkDHPCApJLwV+uvX1qwxP+tEwBPi7CwhIzyGaCMlazySnHdJturiTzAXQ== X-Received: by 2002:a05:6a21:998b:b0:35d:7f7:4aac with SMTP id adf61e73a8af0-36617ed7cc7mr3771999637.47.1765078446332; Sat, 06 Dec 2025 19:34:06 -0800 (PST) From: ChenMiao To: zhao1.liu@intel.com, pbonzini@redhat.com, manos.pitsidianakis@linaro.org, richard.henderson@linaro.org, philmd@linaro.org Cc: chao.liu@openatom.club , dzm91@openatom.club , qemu-rust@nongnu.org, qemu-devel@nongnu.org, hust-os-kernel-patches@googlegroups.com, chenmiao Subject: [PATCH v3 4/4] rust/hw/gpio: Add the the first gpio device pcf8574 Date: Sun, 7 Dec 2025 03:33:31 +0000 Message-ID: <2d5800af31f4d8f4b33aadef49f0e6999067bd16.1765077679.git.chenmiao@openatom.club> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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=2607:f8b0:4864:20::42d; envelope-from=chenmiao.ku@gmail.com; helo=mail-pf1-x42d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sat, 06 Dec 2025 23:34:11 -0500 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 @gmail.com) X-ZM-MESSAGEID: 1765082087461154100 From: chenmiao After implementing the I2CBus and I2CSlave, we proceeded to implement a bas= ic GPIO device =E2=80=94 the PCF8574 =E2=80=94 which depends on I2CSlave. This patch must depend on the below link to compile normally: https://lists.nongnu.org/archive/html/qemu-devel/2025-10/msg07356.html At present, I have summarized the general workflow for device modeling in R= ust as follows: 1. Modify the configuration under hw/deviceto distinguish between C and Rust versions. 2. Create a device crate under rust/hw. 3. Add (or copy) the necessary wrappers, build.rs, and bindings. 4. Begin the device modeling process. 5. Construct the corresponding structures in Rust that mirror those in C, especially for =E2=80=9Cmembers that may change=E2=80=9D. 6. Referencing the C implementation, define initialization functions and establish parent-class relationships for the Rust structure. 7. Set up ObjectImpl, DeviceImpl, and ResettablePhasesImpl. 8. Configure vmstate. 9. Implement other functional methods. Signed-off-by: Chen Miao --- hw/gpio/Kconfig | 5 + hw/gpio/meson.build | 2 +- rust/Cargo.lock | 18 +++- rust/Cargo.toml | 1 + rust/hw/Kconfig | 1 + rust/hw/gpio/Kconfig | 2 + rust/hw/gpio/meson.build | 1 + rust/hw/gpio/pcf8574/Cargo.toml | 28 +++++ rust/hw/gpio/pcf8574/meson.build | 37 +++++++ rust/hw/gpio/pcf8574/src/lib.rs | 178 +++++++++++++++++++++++++++++++ rust/hw/meson.build | 1 + 11 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 rust/hw/gpio/Kconfig create mode 100644 rust/hw/gpio/meson.build create mode 100644 rust/hw/gpio/pcf8574/Cargo.toml create mode 100644 rust/hw/gpio/pcf8574/meson.build create mode 100644 rust/hw/gpio/pcf8574/src/lib.rs diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig index a209294c20..1be534aaf6 100644 --- a/hw/gpio/Kconfig +++ b/hw/gpio/Kconfig @@ -27,6 +27,11 @@ config PCA9554 config PCF8574 bool depends on I2C + select PCF8574_C if !HAVE_RUST + select X_PCF8574_RUST if HAVE_RUST + +config PCF8574_C + bool =20 config ZAURUS_SCOOP bool diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build index 74840619c0..9e4b1a8fd7 100644 --- a/hw/gpio/meson.build +++ b/hw/gpio/meson.build @@ -17,4 +17,4 @@ system_ss.add(when: 'CONFIG_RASPI', if_true: files( system_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_gpio= .c')) system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c')) system_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c')) -system_ss.add(when: 'CONFIG_PCF8574', if_true: files('pcf8574.c')) +system_ss.add(when: 'CONFIG_PCF8574_C', if_true: files('pcf8574.c')) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 0c1df625df..2db2f70e8a 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version =3D 3 +version =3D 4 =20 [[package]] name =3D "anyhow" @@ -204,6 +204,22 @@ dependencies =3D [ "util", ] =20 +[[package]] +name =3D "pcf8574" +version =3D "0.1.0" +dependencies =3D [ + "bits", + "bql", + "common", + "glib-sys", + "hwcore", + "migration", + "qom", + "system", + "trace", + "util", +] + [[package]] name =3D "pkg-config" version =3D "0.3.32" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 783e626802..6a17eefe49 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -10,6 +10,7 @@ members =3D [ "system", "hw/core", "hw/char/pl011", + "hw/gpio/pcf8574", "hw/timer/hpet", "trace", "util", diff --git a/rust/hw/Kconfig b/rust/hw/Kconfig index 36f92ec028..ba1297ca2d 100644 --- a/rust/hw/Kconfig +++ b/rust/hw/Kconfig @@ -1,3 +1,4 @@ # devices Kconfig source char/Kconfig +source gpio/Kconfig source timer/Kconfig diff --git a/rust/hw/gpio/Kconfig b/rust/hw/gpio/Kconfig new file mode 100644 index 0000000000..c47aa76f14 --- /dev/null +++ b/rust/hw/gpio/Kconfig @@ -0,0 +1,2 @@ +config X_PCF8574_RUST + bool diff --git a/rust/hw/gpio/meson.build b/rust/hw/gpio/meson.build new file mode 100644 index 0000000000..908991ad13 --- /dev/null +++ b/rust/hw/gpio/meson.build @@ -0,0 +1 @@ +subdir('pcf8574') diff --git a/rust/hw/gpio/pcf8574/Cargo.toml b/rust/hw/gpio/pcf8574/Cargo.t= oml new file mode 100644 index 0000000000..a3bd82f93d --- /dev/null +++ b/rust/hw/gpio/pcf8574/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name =3D "pcf8574" +version =3D "0.1.0" +authors =3D ["Chen Miao "] +description =3D "pcf8574 device model for QEMU" +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] +glib-sys.workspace =3D true +bits =3D { path =3D "../../../bits" } +common =3D { path =3D "../../../common" } +util =3D { path =3D "../../../util" } +bql =3D { path =3D "../../../bql" } +migration =3D { path =3D "../../../migration" } +qom =3D { path =3D "../../../qom" } +system =3D { path =3D "../../../system" } +hwcore =3D { path =3D "../../../hw/core" } +trace =3D { path =3D "../../../trace" } + +[lints] +workspace =3D true diff --git a/rust/hw/gpio/pcf8574/meson.build b/rust/hw/gpio/pcf8574/meson.= build new file mode 100644 index 0000000000..f0b7f9e687 --- /dev/null +++ b/rust/hw/gpio/pcf8574/meson.build @@ -0,0 +1,37 @@ +# TODO: Remove this comment when the clang/libclang mismatch issue is solv= ed. +# +# Rust bindings generation with `bindgen` might fail in some cases where t= he +# detected `libclang` does not match the expected `clang` version/target. = In +# this case you must pass the path to `clang` and `libclang` to your build +# command invocation using the environment variables CLANG_PATH and +# LIBCLANG_PATH +_libpcf8574_rs =3D static_library( + 'pcf8574', + structured_sources( + [ + 'src/lib.rs', + ], + ), + override_options: ['rust_std=3D2021', 'build.rust_std=3D2021'], + rust_abi: 'rust', + dependencies: [ + bilge_rs, + bilge_impl_rs, + bits_rs, + common_rs, + glib_sys_rs, + util_rs, + migration_rs, + bql_rs, + qom_rs, + chardev_rs, + system_rs, + hwcore_rs, + trace_rs + ], +) + +rust_devices_ss.add(when: 'CONFIG_X_PCF8574_RUST', if_true: [declare_depen= dency( + link_whole: [_libpcf8574_rs], + variables: {'crate': 'pcf8574'}, +)]) diff --git a/rust/hw/gpio/pcf8574/src/lib.rs b/rust/hw/gpio/pcf8574/src/lib= .rs new file mode 100644 index 0000000000..4bec081876 --- /dev/null +++ b/rust/hw/gpio/pcf8574/src/lib.rs @@ -0,0 +1,178 @@ +// Copyright 2025 HUST OpenAtom Open Source Club. +// Author(s): Chen Miao +// SPDX-License-Identifier: GPL-2.0-or-later + +use std::slice::from_ref; + +use bql::BqlRefCell; +use common::bitops::IntegerExt; +use hwcore::{ + DeviceClass, DeviceImpl, DeviceMethods, DeviceState, I2CResult, I2CSla= ve, I2CSlaveImpl, + InterruptSource, ResetType, ResettablePhasesImpl, +}; +use migration::{ + self, impl_vmstate_struct, vmstate_fields, vmstate_of, VMStateDescript= ion, + VMStateDescriptionBuilder, +}; +use qom::{qom_isa, IsA, Object, ObjectImpl, ObjectType, ParentField}; + +pub const TYPE_PCF8574: &::std::ffi::CStr =3D c"pcf8574"; +const PORTS_COUNT: usize =3D 8; + +#[repr(C)] +#[derive(Clone, Copy, Debug, Default)] +pub struct PCF8574Inner { + pub lastrq: u8, + pub input: u8, + pub output: u8, +} + +impl PCF8574Inner { + pub fn line_state(&self) -> u8 { + self.input & self.output + } + + pub fn set_output(&mut self, data: u8) -> (u8, u8) { + let prev =3D self.line_state(); + self.output =3D data; + let actual =3D self.line_state(); + (prev, actual) + } + + pub fn set_input(&mut self, start: u32, value: u8) -> bool { + self.input =3D self.input.deposit(start, 1, value); + self.has_state_changed() + } + + pub fn receive(&mut self) -> (bool, u8) { + let state_changed =3D self.has_state_changed(); + if state_changed { + self.lastrq =3D self.line_state(); + } + (state_changed, self.lastrq) + } + + pub fn has_state_changed(&self) -> bool { + self.line_state() !=3D self.lastrq + } +} + +#[repr(C)] +#[derive(qom::Object, hwcore::Device)] +pub struct PCF8574State { + pub parent_obj: ParentField, + pub inner: BqlRefCell, + pub handler: [InterruptSource; PORTS_COUNT], + pub intrq: InterruptSource, +} + +// static_assert!(size_of::() <=3D size_of::()); + +qom_isa!(PCF8574State: I2CSlave, DeviceState, Object); + +#[allow(dead_code)] +trait PCF8574Impl: I2CSlaveImpl + IsA {} + +unsafe impl ObjectType for PCF8574State { + type Class =3D DeviceClass; + const TYPE_NAME: &'static std::ffi::CStr =3D crate::TYPE_PCF8574; +} + +impl PCF8574Impl for PCF8574State {} + +impl ObjectImpl for PCF8574State { + type ParentType =3D I2CSlave; + const CLASS_INIT: fn(&mut Self::Class) =3D Self::Class::class_init::; +} + +impl DeviceImpl for PCF8574State { + const VMSTATE: Option> =3D Some(VM= STATE_PCF8574); + const REALIZE: Option util::Result<()>> =3D Some(Self::re= alize); +} + +impl ResettablePhasesImpl for PCF8574State { + const HOLD: Option =3D Some(Self::reset_hold); +} + +impl I2CSlaveImpl for PCF8574State { + const SEND: Option I2CResult> =3D Some(Self::se= nd); + const RECV: Option u8> =3D Some(Self::recv); +} + +impl PCF8574State { + fn send(&self, data: u8) -> I2CResult { + let (prev, actual) =3D self.inner.borrow_mut().set_output(data); + + let mut diff =3D actual ^ prev; + while diff !=3D 0 { + let line =3D diff.trailing_zeros() as u8; + if let Some(handler) =3D self.handler.get(line as usize) { + handler.set((actual >> line) & 1 =3D=3D 1); + } + diff &=3D !(1 << line); + } + + self.intrq.set(actual =3D=3D self.inner.borrow().lastrq); + + I2CResult::ACK + } + + fn recv(&self) -> u8 { + let (has_changed, actual) =3D self.inner.borrow_mut().receive(); + if has_changed { + self.intrq.raise(); + } + + actual + } + + fn realize(&self) -> util::Result<()> { + self.init_gpio_in(self.handler_size(), PCF8574State::gpio_set); + self.init_gpio_out(from_ref(&self.handler[0])); + self.init_gpio_out_named(from_ref(&self.intrq), "nINT", 1); + Ok(()) + } + + fn gpio_set(&self, line: u32, level: u32) { + assert!(line < self.handler_size()); + + if self + .inner + .borrow_mut() + .set_input(line, u8::from(level !=3D 0)) + { + self.intrq.raise(); + } + } + + fn handler_size(&self) -> u32 { + self.handler.len() as u32 + } + + fn reset_hold(&self, _type: ResetType) {} +} + +impl_vmstate_struct!( + PCF8574Inner, + VMStateDescriptionBuilder::::new() + .name(c"pcf8574/inner") + .version_id(0) + .minimum_version_id(0) + .fields(vmstate_fields! { + vmstate_of!(PCF8574Inner, lastrq), + vmstate_of!(PCF8574Inner, input), + vmstate_of!(PCF8574Inner, output), + }) + .build() +); + +pub const VMSTATE_PCF8574: VMStateDescription =3D + VMStateDescriptionBuilder::::new() + .name(c"pcf8574") + .version_id(0) + .minimum_version_id(0) + .fields(vmstate_fields! { + vmstate_of!(PCF8574State, parent_obj), + vmstate_of!(PCF8574State, inner), + }) + .build(); diff --git a/rust/hw/meson.build b/rust/hw/meson.build index 9749d4adfc..d6b273170e 100644 --- a/rust/hw/meson.build +++ b/rust/hw/meson.build @@ -1,2 +1,3 @@ subdir('char') +subdir('gpio') subdir('timer') --=20 2.43.0