From nobody Sat Jul 25 00:16:38 2026 Received: from LO3P265CU004.outbound.protection.outlook.com (mail-uksouthazon11020086.outbound.protection.outlook.com [52.101.196.86]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 594C85C613; Tue, 21 Jul 2026 16:54:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.196.86 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652879; cv=fail; b=AvD/ItOdGFhcnRH73Ljy/zM6TtleDfnwMkcGgzjsd/AQE/Jab1vD+NLa7E30rC5genJuhAGjB7qgm1ioZ9LGWb/ZuHepURQcKTlUj8aTAqMK4nXDEJ/JDB4qVuceQthogfxDFmxufv0G7mFu+ph643okHMvjlTf9TDoH61n88rM= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652879; c=relaxed/simple; bh=4xGCDf5PobFlcVHfZZcN3wpd3WKhjw3CCXz8HU8+f0k=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=gvefvJB48svIxy/KqwunrZkAgzPkAY9oSnqAAeaCSz8vcLZa6D9HOm1DnA5qDlDJSWw015dBZKJLgNlhZhcRmDv7INtxejqqLc95LBY3lnkZQIS9DIO7XBLcwxhIMFrqn8cQoZbZlF6ePMFhvOd7PRacj7NrvAvS5g4mjXujpqo= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net; spf=pass smtp.mailfrom=garyguo.net; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b=HykDDPEK; arc=fail smtp.client-ip=52.101.196.86 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=garyguo.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b="HykDDPEK" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Dgy2LPlB8MaN6ce0Nv30CINbAUVLFxLSxREx3HJbGNYvtk0/8NudJZnOn6yf7VxSOqN0AEit8LyFEKSFMEtkNPLnwVlAAP7VPpZu0c1YbnfF5kEbnx2sSam5hQh6Upvnus2On1bBO4oiMFg2AEcgRpgX7yudNLX8StNfJI7cZYlLe028lgG04QIBuwiKGz0+vYC2snvFrphoQZ39Xqlu17P5at1vGPHWi8CzANF9P6NG3wanYAIPjJERDYEm4dOfk8IBRIMO3PrEuX9fMswAr2UEuXXzUL3Son48kwVWMaWW1Mg/TzQ1J1R39y2bxPG/GAnFc90VQl7c4N5dgy/z1g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=pQSlD2okbMxmDByMY0NDFaKyI69PtZ5jkloRhFMO7Y4=; b=ZYTUqNkGn3DcHYv+UHZNOWtEItH9G9Dl8F4D6gullKq0LjgyzuJFTL4pqYmeA1jb4y2ESha5FaVXx2755D3w4APGmALwAKqlc0KhJn94HYZANtdEirFw+yByyf4pXeET1mlYowqo+Ybzi9WW43OnzK+gKOZYvDnzdwLku3IGBgaM7rhE6lG15qd3U14lSRA11E5dFFUvvgov5YVkXEwgYFXt0dD44iEBY8kdeIFjKXgVNAGYBpiwEIaGrkaQ+nUmbIInUQv9u1AOc9EMmgPB8dxiSQkfWTQNuv1L5R1uQGsHnY8ro1lWelhYjR0ADIMV7SkYcYu5NEt1e6RXhgljOA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=garyguo.net; dmarc=pass action=none header.from=garyguo.net; dkim=pass header.d=garyguo.net; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=garyguo.net; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=pQSlD2okbMxmDByMY0NDFaKyI69PtZ5jkloRhFMO7Y4=; b=HykDDPEKCBorJ88H3mtLlyykf686ALPjmDdG5Ca22Ly2SPSvFIOBP46F4GANxVHddamargkXtNYd6Mtuv463pBncRCFsPkAGEuvdr3lLjtY5p17S/ozjHyc2rHmNbck+aIOz4NmbjFxiRhbaSQyZKu9DrW7E7VF4WsVeWKGYlm4= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=garyguo.net; Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) by LO8P265MB7878.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:3ae::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Tue, 21 Jul 2026 16:54:34 +0000 Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986]) by LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986%4]) with mapi id 15.21.0223.017; Tue, 21 Jul 2026 16:54:34 +0000 From: Gary Guo Date: Tue, 21 Jul 2026 17:54:25 +0100 Subject: [PATCH 01/10] rust: io: register: allow explicit base type specification Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-typed_register-v1-1-452d72b60262@garyguo.net> References: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> In-Reply-To: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> To: Danilo Krummrich , Alice Ryhl , Daniel Almeida , Miguel Ojeda , Boqun Feng , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , David Airlie , Simona Vetter , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= Cc: driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, linux-pci@vger.kernel.org, Gary Guo X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784652872; l=8773; i=gary@garyguo.net; s=20221204; h=from:subject:message-id; bh=4xGCDf5PobFlcVHfZZcN3wpd3WKhjw3CCXz8HU8+f0k=; b=oaKOqpH8wtNQ3+XFDkY5oDFQGe7nJPZDfogjm/DSM6x5VqO5usNei/DzpJcM1CIR7hCmM2jao IOQN1R8pIoDBgODvPLkPt9Utm/ECA+dUIkEE4WtsVmwiG9yBWCgtEnX X-Developer-Key: i=gary@garyguo.net; a=ed25519; pk=vB3uIX95SM4eVrIqo1DWNWKDKD2xzB+yLLLr0yOPYMo= X-ClientProxiedBy: LO4P123CA0143.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:193::22) To LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LOVP265MB8871:EE_|LO8P265MB7878:EE_ X-MS-Office365-Filtering-Correlation-Id: 74c92060-225c-4156-c359-08dee748bd85 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|7416014|10070799003|1800799024|366016|56012099006|10067099003|22082099003|18002099003|921020; X-Microsoft-Antispam-Message-Info: rgYoD7CWhtXMvfNWAimT3uz/GTz0ltJ9F8BE9xrbD3uLGRaAvAfbTHvl0TlF4itm874rfxncUfqwZvMuc39HCXWDjrOpXbHzdqHm81vboSbA7/7BdzkF5zwueqgUvoZPxlhIUpCwcckFhNeKMZFCsa7dTb9iGYZBqJTGLexTYrKE2vV8Wcxy9tv2yhWxgTMYJLRnwFCVoVtOUNmfwl0fosG0dG6oUIZMfhI6EuAyC5SaPI0kapeCNGmWUaSIMpTwrfSL8DIFp6IBqmLeAOxS5mNzCiLNsLvNaqqXycfI3LsXq13v1fNg2dhCqsHIJ0Y9HevoZg2qH8yoc8IalXVx+/rI9NLwDZmUsJ7b6Fwy07O7gJV0zYTuPtrt7zxXV6XyoaPnyEMQoQrVD9e3Z3pY9OSe4xaxYTmIboSqNJ0YEIkFXRT1UIgYQ+KwUegH/JQD4wUnsCJyZInDqxc7xwcR76szL9gXKTQ5ToWaKu91p9BPhJ9OddmysFAGLX2OTr0nhskCvx7nbuR4UIV+lvnjK2JbYEwIqDHkN7L+Kw4fiG0sxEKDeQI2E6e7ZjiGgZoSRmWE3mSpGbSdcpDYz2mhkO42x8XgfZgWqdLqQ1kT83l5yAdUfhroWejzxcJo9fz8xb2k0Hh8aeolbiTRxNP4PTNlQF4NcU4NKRdk/Z6x6Rw/9353CUZUy8E8HsMCiW1XSH16drpWKbuAqLNaRolg6A== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(376014)(7416014)(10070799003)(1800799024)(366016)(56012099006)(10067099003)(22082099003)(18002099003)(921020);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?R2t6bTM5YWxGazdvZERLNjVCYXdEb2p0MVJkYitQMVZzVUtQTXZhek1TaC9B?= =?utf-8?B?SFFFSVhSaW54LzRjUFUvZytIRW5qMUpUQ1JIRmhUczdxNzcyY0lhUldyd016?= =?utf-8?B?dzVmY1AySmw4NElMc0N0TmJPYnJzRnlWczF4REpsQlMzbUhtL1ZxUTM5ZW9i?= =?utf-8?B?QVYxdFpDcnk1V2s3Uy95dUZXR2hIWUVmZytoSTRqMVVXVXJCbzRaRjQwZWk5?= =?utf-8?B?YzJJUFR4bXpJcTV2bG42b0Z1TkYvQ3QwLzF1blc5VXVyRURXOHpRYlNLOVQ3?= =?utf-8?B?SXRWYVcrUTZaM3o4c0JYbkZDN28wMlZBeTlUVDE4VnhpTnhLOFRkSEJ5MTI2?= =?utf-8?B?US9WME9WaDVldStQWlRRNzIwK3dmbFE2M0R6aWZUOUMzRHYzMXI1M2lYS2V2?= =?utf-8?B?cEhDUERxYU9nU0dwZk9yTDZnYXdRbkwyOFBkemZxb0JlQXhvZjFid3BrVGtm?= =?utf-8?B?enY2dFFxb0tWdmFCODVVR2Q4TjNxSlZxQk5lZ2podjgzUWx6UmRJd0Z1dnhw?= =?utf-8?B?NEtXZm9IcnQwSjkyR3A2YlpKWEpDajkraGRzTk5ndXAvcjdtUGkvS3VHYkhN?= =?utf-8?B?eTM1QWFUNFA4bEJMYlVTc1JiTGdLdXdWSzZmeWZPRDEvdkVmbDlPM2c5WUNY?= =?utf-8?B?Y1BBcmhTMUkrUTdxNEJwSlUzNWJ1amxpa2tGaXNsYTZWVEUzMDZuL2QrZ3ZZ?= =?utf-8?B?YURMS0VmOWJ2dVoxL3dmZzQvTXBjL3plRkpZVzliTm9JY2ZYSW9jckkza2M0?= =?utf-8?B?QzBNc2dicjBpeUdxcVBOem1jYm82RmhhZk8zbUxnSUhJcFZsU2pDNnVJdWJz?= =?utf-8?B?UzBTVWtyY0d4RW94a2dXTkFxTXZ5TXdSZ2VZK0pqV0E2T0V6TEVRVjV5eCtL?= =?utf-8?B?OGNvRkFaaU1PZ2pLMTdYaFkwWTVkQ3ZWY2dTcWR1dzU2aXRodVNoQ0UzNzd3?= =?utf-8?B?NThrODlhU01ZUWwxRFM3bHpXa01QbGZ4MkhKZ1pQSitjMnlrK2NBTnhQVFVS?= =?utf-8?B?VTdxT2lxdHpHc3lUbk9YMHFZaXNmVUo3dkdlODE4MGtwSlE5cHlhaStFNklp?= =?utf-8?B?NDVmR2EvQlg2Tk5tcVFiVnV1WjkwWFVrRE1zRDhLRkdnZTBSWHZGSm9ZcTU4?= =?utf-8?B?ZVAvQk1BYUVDUmFwQmRPc2dHMmd1YXZGOEI5dER5ZGt3WDMzUWdoZ0hWSWpP?= =?utf-8?B?TEpqcjRZQmNGbWp0ZlpIL2MxMWRRK1NZL3JHQ056TnYwMmF4R1NkTG9hSkw2?= =?utf-8?B?NUpYSzVyN0dEVWVyQXk4dXFRK2J6dmRtL0dHbGsyb0hBRllZcUduekpyU1kr?= =?utf-8?B?WnlsdEtseFZwVUVjaVo3b3d0OUtCbVl2SkVMakdLempKdGc4Q2pFUUdIVis3?= =?utf-8?B?TWlDSkVVZjVUZS9HZWRQUUJRZzNJKytqQ0NhaUxSbHljR3ZyV3NSZHg5dUNs?= =?utf-8?B?UVRPd2V2TTNmZCtqU1lyOWFZTHFmUVVURGEyT2FCalAzdnhJaE5XTTdSTStT?= =?utf-8?B?eG9iNmYvQ2RTUjhnYzNIUk1Fd0NsUzE1bGd0MlJHaFpINXl0MVBjSkQvVTVC?= =?utf-8?B?RERjNTdwTEhNUmtxbjVtSmhrSEMvazMzZWZLSEQ0SjdqUXVGckZuTVhEM1Jo?= =?utf-8?B?MmZRSE5PVzJDb05ZRWVmeWt5WWpwK1NKQ2tPZ1FaeHFKT1NZQjJnRStRaFFj?= =?utf-8?B?a3RJV1RKNzVZTWFyQ21IVlpxaG9rNXNDMldneS9ucWRPdC9oTmI4b3c1a29u?= =?utf-8?B?d3JTbHI5QXovd3RyMC9SeU82NEZST2ZRWTBUckJDeTYrZ1JveC9JZ25odXd3?= =?utf-8?B?R3VKQldoYmNIeTdpUUFWcXdHZGlybmh5cXBQcndydVZOSGxUZVJxY040ZUZI?= =?utf-8?B?SktxVjZ6ajZSVGV6a2J6S01JNjdqTHFmRTRBS1JQTWdyV25ndTBCKytKUXJn?= =?utf-8?B?bGk4eDhEa2FUZWRJWEwzY2VkSmdNQ3ZYTXcvQjFXanhjK2ZMdVRrQU5Bc2Zl?= =?utf-8?B?VnNBRUluTEZKU2NzSjdmaUtvWWc3Qkl0TXlaTFFTRHMyMmw5THVSM1RJWVhB?= =?utf-8?B?SHIyYURIRHRxam1lajZ0L3IrWTRMck16SWlOSEc3dTF6V2hKdnF0Vm9FekUy?= =?utf-8?B?SzkrVDEreXMxRXJFSnQyS04yQ1dqQ0t5R0xnczNSaVdkOWNwOFVwdEh6ZGRo?= =?utf-8?B?Yks2V3NlNWFkV0xhTGdBYThYbTM3c2RBR1ZsUUl3U2ZWQXl2YlNiaG4rUXJV?= =?utf-8?B?ckJSTG0wWmtSYnlNaVNlSzMwZ0hEaTY5VjVkSWFIVWR4YVEwZ1E1YkxYTnF3?= =?utf-8?B?SWx0QVhMK2FtNUxHT2pKNHpoRVFIazRVNVlZb3hpTXM1bUNxM1dHdz09?= X-OriginatorOrg: garyguo.net X-MS-Exchange-CrossTenant-Network-Message-Id: 74c92060-225c-4156-c359-08dee748bd85 X-MS-Exchange-CrossTenant-AuthSource: LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jul 2026 16:54:33.6963 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bbc898ad-b10f-4e10-8552-d9377b823d45 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: FSbBwgu9xyV6/9GoununumtHZljpychy5llmGHc/l71+NGaLXUiBAD6U4++ck0/tR+5N4+GlzjGSyYYsAUOgXA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LO8P265MB7878 Currently registers work for all untyped I/O regions, which is not ideal. It allows registers defined for device A to work for another device B and there is no safeguarding at all. All users of the `register!` macro know what type it will be operating on, and that type is consistent across the driver. Therefore, add a `base` parameter to `register!`. Currently this parameter is unused in the generated code; it will be used when all users of `register!` is converted to gain the parameter. Signed-off-by: Gary Guo --- rust/kernel/io.rs | 4 +++ rust/kernel/io/register.rs | 79 ++++++++++++++++++++++++++++++++++++++++++= ---- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs index 95f46bb75f9e..c5f07c38e59e 100644 --- a/rust/kernel/io.rs +++ b/rust/kernel/io.rs @@ -883,6 +883,8 @@ fn try_write(self, location: L, value: T) -> Resu= lt /// }; /// /// register! { + /// base: Region; + /// /// VERSION(u32) @ 0x100 { /// 15:8 major; /// 7:0 minor; @@ -1028,6 +1030,8 @@ fn write(self, location: L, value: T) /// }; /// /// register! { + /// base: Region<0x1000>; + /// /// VERSION(u32) @ 0x100 { /// 15:8 major; /// 7:0 minor; diff --git a/rust/kernel/io/register.rs b/rust/kernel/io/register.rs index 6cb07fc92cc3..b0fcfce36c9c 100644 --- a/rust/kernel/io/register.rs +++ b/rust/kernel/io/register.rs @@ -13,9 +13,14 @@ //! # Simple example //! //! ```no_run -//! use kernel::io::register; +//! use kernel::io::{ +//! register, +//! Region, +//! }; //! //! register! { +//! base: Region<0x1000>; +//! //! /// Basic information about the chip. //! pub BOOT_0(u32) @ 0x00000100 { //! /// Vendor ID. @@ -55,11 +60,14 @@ //! register, //! Io, //! IoLoc, +//! Region, //! }, //! num::Bounded, //! }; -//! # use kernel::io::{Mmio, Region}; +//! # use kernel::io::Mmio; //! # register! { +//! # base: Region<0x1000>; +//! # //! # pub BOOT_0(u32) @ 0x00000100 { //! # 15:8 vendor_id; //! # 7:4 major_revision; @@ -444,11 +452,14 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// io::{ /// register, /// Io, +/// Region, /// }, /// }; -/// # use kernel::io::{Mmio, Region}; +/// # use kernel::io::Mmio; /// /// register! { +/// base: Region<0x1000>; +/// /// FIXED_REG(u32) @ 0x100 { /// 15:8 high_byte; /// 7:0 low_byte; @@ -479,9 +490,14 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// the context: /// /// ```no_run -/// use kernel::io::register; +/// use kernel::io::{ +/// register, +/// Region, +/// }; /// /// register! { +/// base: Region<0x1000>; +/// /// /// Scratch register. /// pub SCRATCH(u32) @ 0x00000200 { /// 31:0 value; @@ -531,6 +547,7 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// /// ```ignore /// register! { +/// ... /// pub RELATIVE_REG(u32) @ Base + 0x80 { /// ... /// } @@ -557,9 +574,10 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// WithBase, /// }, /// Io, +/// Region, /// }, /// }; -/// # use kernel::io::{Mmio, Region}; +/// # use kernel::io::Mmio; /// /// // Type used to identify the base. /// pub struct CpuCtlBase; @@ -578,6 +596,8 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// /// // This makes `CPU_CTL` accessible from all implementors of `RegisterB= ase`. /// register! { +/// base: Region<0x1000>; +/// /// /// CPU core control. /// pub CPU_CTL(u32) @ CpuCtlBase + 0x10 { /// 0:0 start; @@ -594,6 +614,8 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// /// // Aliases can also be defined for relative register. /// register! { +/// base: Region<0x1000>; +/// /// /// Alias to CPU core control. /// pub CPU_CTL_ALIAS(u32) =3D> CpuCtlBase + CPU_CTL { /// /// Start the aliased CPU core. @@ -636,15 +658,18 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// register, /// register::Array, /// Io, +/// Region, /// }, /// }; -/// # use kernel::io::{Mmio, Region}; +/// # use kernel::io::Mmio; /// # fn get_scratch_idx() -> usize { /// # 0x15 /// # } /// /// // Array of 64 consecutive registers with the same layout starting at = offset `0x80`. /// register! { +/// base: Region<0x1000>; +/// /// /// Scratch registers. /// pub SCRATCH(u32)[64] @ 0x00000080 { /// 31:0 value; @@ -670,6 +695,8 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// // Alias to a specific register in an array. /// // Here `SCRATCH[8]` is used to convey the firmware exit code. /// register! { +/// base: Region<0x1000>; +/// /// /// Firmware exit status code. /// pub FIRMWARE_STATUS(u32) =3D> SCRATCH[8] { /// 7:0 status; @@ -682,6 +709,8 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// // Here, each of the 16 registers of the array is separated by 8 bytes= , meaning that the /// // registers of the two declarations below are interleaved. /// register! { +/// base: Region<0x1000>; +/// /// /// Scratch registers bank 0. /// pub SCRATCH_INTERLEAVED_0(u32)[16, stride =3D 8] @ 0x000000c0 { /// 31:0 value; @@ -703,6 +732,7 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// /// ```ignore /// register! { +/// ... /// pub RELATIVE_REGISTER_ARRAY(u8)[10, stride =3D 4] @ Base + 0x100 { /// ... /// } @@ -722,9 +752,10 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// WithBase, /// }, /// Io, +/// Region, /// }, /// }; -/// # use kernel::io::{Mmio, Region}; +/// # use kernel::io::Mmio; /// # fn get_scratch_idx() -> usize { /// # 0x15 /// # } @@ -746,6 +777,8 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// /// // 64 per-cpu scratch registers, arranged as a contiguous array. /// register! { +/// base: Region<0x1000>; +/// /// /// Per-CPU scratch registers. /// pub CPU_SCRATCH(u32)[64] @ CpuCtlBase + 0x00000080 { /// 31:0 value; @@ -773,6 +806,8 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// /// // Alias to `SCRATCH[8]` used to convey the firmware exit code. /// register! { +/// base: Region<0x1000>; +/// /// /// Per-CPU firmware exit status code. /// pub CPU_FIRMWARE_STATUS(u32) =3D> CpuCtlBase + CPU_SCRATCH[8] { /// 7:0 status; @@ -783,6 +818,8 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// // Here, each of the 16 registers of the array is separated by 8 bytes= , meaning that the /// // registers of the two declarations below are interleaved. /// register! { +/// base: Region<0x1000>; +/// /// /// Scratch registers bank 0. /// pub CPU_SCRATCH_INTERLEAVED_0(u32)[16, stride =3D 8] @ CpuCtlBase = + 0x00000d00 { /// 31:0 value; @@ -801,6 +838,34 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// ``` #[macro_export] macro_rules! register { + // Entry point for the macro, allowing multiple registers to be define= d in one call. + // It matches all possible register declaration patterns to dispatch t= hem to corresponding + // `@reg` rule that defines a single register. + ( + base: $reg_base:ty; + $( + $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) + $([ $size:expr $(, stride =3D $stride:expr)? ])? + $(@ $($base:ident +)? $offset:literal)? + $(=3D> $alias:ident $(+ $alias_offset:ident)? $([$alias_id= x:expr])? )? + { $($fields:tt)* } + )* + ) =3D> { + const _: () =3D { + #[allow(unused)] + fn test_base(_: &$reg_base) {} + }; + + $( + $crate::register!( + @reg $(#[$attr])* $vis $name ($storage) $([$size $(, stride = =3D $stride)?])? + $(@ $($base +)? $offset)? + $(=3D> $alias $(+ $alias_offset)? $([$alias_idx])? )? + { $($fields)* } + ); + )* + }; + // Entry point for the macro, allowing multiple registers to be define= d in one call. // It matches all possible register declaration patterns to dispatch t= hem to corresponding // `@reg` rule that defines a single register. --=20 2.54.0 From nobody Sat Jul 25 00:16:38 2026 Received: from LO3P265CU004.outbound.protection.outlook.com (mail-uksouthazon11020086.outbound.protection.outlook.com [52.101.196.86]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A8A7037C0FF; Tue, 21 Jul 2026 16:54:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.196.86 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652884; cv=fail; b=CK+8UF3ZuhGDv8KACGZIHZSHCTNz9n7v9Q0pgM5gRkbcqT4zNDkYPh+Kc6Ye1N8pPfC3808pEY4xXFoY1XBDcpB5USMACUwIasTqDvOcXLHg0c+51BDCn+3E0on8hjXNUOszT6mIZKduWbNV8psfcMATADNmUcM3OHAucX3qpqA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652884; c=relaxed/simple; bh=RKlPXQIeVwE25TJbDbo2jJ1JHqp1gKN62EqUDFh5udE=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=g/GdRY3Fzo/Rss2Yw8GynC/hkF1XylMQlG/daQR7vFIuRYso9TLzqNg9Dfc7xD1A0rG6KV0MGZeTHh4jQojLUdMxRedo0/YmcEWDp0v8XFhAseZFR7gpfyDiy6D4ulGFQbv1v4UE8XaIxWK2OSjVsXoxQt33tHPLhiY+LM95Nzw= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net; spf=pass smtp.mailfrom=garyguo.net; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b=urGWbtut; arc=fail smtp.client-ip=52.101.196.86 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=garyguo.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b="urGWbtut" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=mGZW3g9AMH1yNAFfsEYjjdIigTrtCauK9iQJIJe3xLDepQBHx+RRW96Mr2D3c+SiaQHeiHz81FNH92huq1TZ682TzBWKpgISQhBwyGpSrbx0kXr4sSe3bfbbCwvTHw0xYNLTyGBzZVq15qbO7xpi5aQnmMDoCrp9Hx8hOVd0VJTWf5/dbG7RiYNEGuiZMro/HdvTNGpC+Ydyw53/8CASw/QJhr+yqRwAndCEuTzlVIx/SjIXk1Vyj0Sv38xRnuTb1O+peZH/9ZDS7xRkWcvMdkOfUXnd/Q7nifiWlYVoK7eMOacIN1zuCT352G2lxZq54458M5MB2ZH0OOEnEtbNZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=As+buIbTDyIVvTDk4Plvpn/1BAjMTteMMWjIWgKGcJM=; b=RAQ3zC5kwH/xwXQgDFMuJ6EmniIrddTrgtLgwXVo/GKg+FiF+cSr9eCpHXmBstY3xV1UUxBPkAFK/YxccPW/jJgGZWohdor4EWdlhmwTCP/yqMzb4Kf2sfPtkANMmHsF5vXnYn9xMR6PIK6WXcDHhxdKwvEobOz/5b2ipmIzwVYZMT/eI5Ac7F0RY1ZX8ZE3xWBFroFcW8/968++wblNlbxPRQDnX71PjjHTmddZW6WPzXhTXm8WyHsxlameqGkC3frt7ZzGw1gD20ETo6pU9DnauLt1yJbtMAsQUbZtM0WA/dgYgNJlLpID8rvYcUPWbUdoqQEJXZYvW9JeKhH4Jg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=garyguo.net; dmarc=pass action=none header.from=garyguo.net; dkim=pass header.d=garyguo.net; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=garyguo.net; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=As+buIbTDyIVvTDk4Plvpn/1BAjMTteMMWjIWgKGcJM=; b=urGWbtut8F68WPF10UvqzzCE9G0ovY1dvfUnnpw+HvAviIFKq1DubIeDO/4R6y3a7AyEPQCcD+Lqi3f0Bd/l3ESs4qTGu/rhbpnHnPryZ8TNf2LqyvizSEbHTMQJAKkXfgsQe09nbgTlYseLoIUkSSBBlf61g+hoA0uZA2gZcns= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=garyguo.net; Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) by LO8P265MB7878.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:3ae::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Tue, 21 Jul 2026 16:54:34 +0000 Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986]) by LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986%4]) with mapi id 15.21.0223.017; Tue, 21 Jul 2026 16:54:34 +0000 From: Gary Guo Date: Tue, 21 Jul 2026 17:54:26 +0100 Subject: [PATCH 02/10] gpu: nova-core: specify base type for registers Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-typed_register-v1-2-452d72b60262@garyguo.net> References: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> In-Reply-To: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> To: Danilo Krummrich , Alice Ryhl , Daniel Almeida , Miguel Ojeda , Boqun Feng , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , David Airlie , Simona Vetter , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= Cc: driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, linux-pci@vger.kernel.org, Gary Guo X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784652872; l=8641; i=gary@garyguo.net; s=20221204; h=from:subject:message-id; bh=RKlPXQIeVwE25TJbDbo2jJ1JHqp1gKN62EqUDFh5udE=; b=G2V0jN3aVmE+51teSWwx/lqrkwktnviNtrT5f01Ff2nC2mXj1BvlM3cCoZe2unM9iqjK+FSG/ vt2ZuB1m9ggCP5VFzTTPp07e8LnC+x76zbLX+b8cmcXbZCnwUd9hh+0 X-Developer-Key: i=gary@garyguo.net; a=ed25519; pk=vB3uIX95SM4eVrIqo1DWNWKDKD2xzB+yLLLr0yOPYMo= X-ClientProxiedBy: LO4P123CA0143.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:193::22) To LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LOVP265MB8871:EE_|LO8P265MB7878:EE_ X-MS-Office365-Filtering-Correlation-Id: 48250de1-954f-4b6a-9448-08dee748bdd3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|7416014|10070799003|1800799024|366016|56012099006|10067099003|22082099003|18002099003|921020; X-Microsoft-Antispam-Message-Info: fUy3t1PN5LtoqYRDNig0R5MVdlkDcODgue4zElED7NQHV7kr+cr8UyvsQvBfAjsEw3yxXB+TPihBdvrMufRWnYhEhitKBChskTlFgGWSfHnTIeaLFR/5vW8t/nxXNvASFCcxILioJfEbWmSeXG2ptmwHp+k1EDVD74TgRVlbgSm2kflOfFEiwZJjTtXCPDDOrxvgaTvoNFRTKWojnIkFlB4YMT5dv+1GF3GXVvs+gmQrABPVhxoTjwbZHOHLhslzJysTocPrrEr88k7tB3/PbtfVwSm7Kdbv56/m/QfhgDPhp43EQ7VVXm5/bSY9S/oWZwUZ2orlg/8yEpzpHlz74+gZgdz1pjMAtbHkRax5+EN491ELmnGo7fgzLF0oJPUjBFqBEv6JdhfkY0h4ul+SgdChtqyFlXdR0SAwO/HHTPCYenaQ6e7h9FFcUEAfMLd/Svy49Qx+LApNHeY7cdRCgEuue1Tfzp1P0JeWQAlXX+TtjBqYHvE2rUAJxsPrQoqePAy/VobCu3RGH6hSUU/rJbMlATQ8QJgHHM+WJ8DGVvzzHO+jDKH8NFm/uJpb9h7cwxThWpXg5ELmnDOBy3mTXpfV2FqUSxZ66w9rq7cue1vrrlyTZ7MMPaPR8KqXdqwzy+KtPAS9z5A99/l6btzfTCMXwCskdgTiJ4k0OkAHZSO3enAhRgieyI75rQc5j6y/Dmslz993n++SEkP73FpMUw== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(376014)(7416014)(10070799003)(1800799024)(366016)(56012099006)(10067099003)(22082099003)(18002099003)(921020);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?eU1ZRm1RclowOWFyNGhKNDNGamRVdlVlK1VBcVN6c0dwU2tqZ2FJeDlMSnM1?= =?utf-8?B?S1ZSSlJCWXV6YnVHYWYyUFFDU3RKSU52V096L0pXeGN5ZmpPcDhMenJYd25F?= =?utf-8?B?b1RMZ3NVQTZ1Q29Dd2hQNStUV1RMcU9TSktMZ2MrR2hDZEFLRmxqdTVUc1Uy?= =?utf-8?B?eFVPWVg2VXRLSERFbk40VVh1cHFoakdOUGg2NU1NMDFoaTdqbngyK3JpbzdY?= =?utf-8?B?cTdaUk96QS80QTZhVFRiN1J6K0J3cjZ3bkROeDJLNG43RnZpdms0YUNiQnVC?= =?utf-8?B?VXVJQUpHZmROcjdpLzRjcU1odmFBYURsQko3T2tMVWRwc1hZWWo5a2ZwbVZ4?= =?utf-8?B?THF1QjQxY0dYSFFXaE1LU0p2ZUJYaFlxM1A2V0dXbm45UUc2bk51OXlDMmlD?= =?utf-8?B?WlZQZXplUkcvcmxHZEdVWkpNMzNNS3VQWlFvU05BOStjMUJGem04RlhzNlBC?= =?utf-8?B?aVVQeGpXZXdMRXQwVE5zYno5SWVqbS8rU2xqa01hbXNHbWM0dU44LzRqcFpU?= =?utf-8?B?NTFmd2tjNlR6aVNYcW5aUmNEYUcvSUVrMFl3cDYrZERiQVUxQXlRRTJTQkMx?= =?utf-8?B?ZTlKcy9KWDJVWTB0akFKeDcvenAzK1c5U3pvR1puQ09EZEcrU0JucE43Z05p?= =?utf-8?B?VElzY0FycTFzZG9aZFRvNG5FVFkzVkxONVVxaVYrdU0xNURGV2pNSENOVEVF?= =?utf-8?B?KzdhWGxRd3dHM0FLMjY3SGpENUlDcWwvazZSTlZXZzljOVpWNEFQM1hrNDNs?= =?utf-8?B?eVovMCt6OGUyanN5RG9pOVNLVzF3ZnJhdjV2aCszS2lYYzg1Rzc5WUVMTDUw?= =?utf-8?B?cm54K2ZWNkNqaDZWZUpvaDVuSW9vREthcFlCU2p3OEhpTzBBOHhoblAwMUR4?= =?utf-8?B?eFpjUUV3MzNNVUNSYkRsSmpNYldnR3ZXVFVac3Aza0pHUzVXUjZhLzVsOE5z?= =?utf-8?B?SHhQNFlEY2JHc3BqNXdLdXFHNURLUFZvSnlPMnc5YlpBaXNLdWhZZEtRazgw?= =?utf-8?B?UEhzT2ZjdjFmZG5wTFA5c2EzUGhFUDRSOS9keWh5UUdCWlpVZ1loZ1NzYTZS?= =?utf-8?B?cFQ0WHVsL3BUU0xDajF0UndSTm9kMktZeVczbUZoSmx4YUdIb1p0eXF4VUZO?= =?utf-8?B?b0dndDliSnQzYUpLeGZQVy90MWtHQnp3eTBYcTg5ajgrcFk2SmhiNVlQb2lo?= =?utf-8?B?UzdVQWpwaTZPMTNMajBJcFlvejhlWGVrdXZEc3R3ODVlaWJtQ2U4NTJRK1lM?= =?utf-8?B?OTQxT1hFOWMxdHc0a0t5NFFyMUhkenQzYjlPUHUrTUVvdHBRUDU5d2p4Mngz?= =?utf-8?B?b0ZIYnBjdW8zdnRYMWxKcmhWNEg0ajA4N1BRRHVSbTEzcnZ6Q0pZMHEyN3Zl?= =?utf-8?B?OU9YRW9OYlU3bDE3QzFZbWpWTTdPWnA0SHRwUVUybDFoNEgzT1QyZTFpWWsy?= =?utf-8?B?TXJIcVJYSVFtVWJ3TWhoUWxMeFp0RjJ0bytPNVl6L2M5aUx4M1htcHgvV3lK?= =?utf-8?B?WVorUGxXcmVLZHZtTzRsVHArMENNUUdCU2FWY1hSb0dSOXkwY3hqS3IwQjNT?= =?utf-8?B?ZjlQRW56NkdJVjRVUjhOYXd6SkpwT2RqYzBCNWs5V1BHbkFWL0NrWEkrNjV2?= =?utf-8?B?Nm02SmRUVERTZDJtVEhKa3BpZ3VXZlVZREFINlRrUkVHemd2MjI2T2ZnN3RT?= =?utf-8?B?bTNsQm4zVTdwUzViQ0t0SEFYVlRGbnVPRkgyYzBUK25Ud3RuaFFITXVNNmJv?= =?utf-8?B?K01JdUlvMjRXTUQzZlU4NlB4RnNGR1F4dmhOUFZLWVI4ZWMzbHlEU1VXTzdE?= =?utf-8?B?bTV4VWNpd1hTRlFTNDZNaFVDSldQODN5eGhFWjRoZXdrbE1WdUZoU0xTdlFK?= =?utf-8?B?RUVmZHpqbjJDSWhTQWxsQXF6VGFGQTA5ZTB4b2tqdkdkeHdGSC8xTkhMTHlW?= =?utf-8?B?bmYrTTM5ZitPWC91L0ZxekZOa3JtVjFMZzNNMFlhSkZiaVBBV1NVWitDS0lZ?= =?utf-8?B?MmVQa0ZVTUF0WWMxQWR4VWlMclNxTHB0Mk1xcnFtQ3ZLUmY1MnZ3Z1FHaEVr?= =?utf-8?B?Y1BmQUF5eFIzMzFjMTlTRFRKWFJ2bzFzRFZFVHIzbXdNRGxYSi9Kb1E1cUJB?= =?utf-8?B?Uys4RGZmTmNmZzMxZEFJZ0NFbHlFWnFmTXdHVHVzTERidlNMTVcya2dhK3dT?= =?utf-8?B?R0JyeGpDSGxUcDFNdFJ4Wm54bDZ3bVc4NWdBQUlUUjNUMVYzQjJRZkNtdlZR?= =?utf-8?B?NzQwK1N3OTNUYWlualFZblIzYVNHSkpLa3ZCRzV6UVZ6RFQzOU54MFRpZGZw?= =?utf-8?B?MDVXNXIxREVYcHptV1R4bnNZdTlDbnIvSGRqUm1zYWNRS0dKdWxndz09?= X-OriginatorOrg: garyguo.net X-MS-Exchange-CrossTenant-Network-Message-Id: 48250de1-954f-4b6a-9448-08dee748bdd3 X-MS-Exchange-CrossTenant-AuthSource: LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jul 2026 16:54:34.2226 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bbc898ad-b10f-4e10-8552-d9377b823d45 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: rOiztYiI2MXh92wh5HWAnqh9V1EmQYPQLJwKqcXbIBP288nInbbp8HToRRNhlH9Xus82x0iJhqkMMUWnpRlC2w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LO8P265MB7878 All registers use the same base type, which is `::Target`. Thus add the base parameter to `register!` invocation. Signed-off-by: Gary Guo --- drivers/gpu/nova-core/driver.rs | 1 + drivers/gpu/nova-core/fb/regs.rs | 4 ++++ drivers/gpu/nova-core/gsp/regs.rs | 4 ++++ drivers/gpu/nova-core/regs.rs | 42 +++++++++++++++++++++++++++++++++++= +++- drivers/gpu/nova-core/vbios.rs | 11 +++++++++- 5 files changed, 60 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver= .rs index 48380ac15f68..fe82363a8201 100644 --- a/drivers/gpu/nova-core/driver.rs +++ b/drivers/gpu/nova-core/driver.rs @@ -37,6 +37,7 @@ pub(crate) struct NovaCore<'bound> { const BAR0_SIZE: usize =3D SZ_16M; =20 pub(crate) type Bar0<'a> =3D &'a pci::Bar<'a, BAR0_SIZE>; +pub(crate) type NovaRegisters =3D kernel::io::Region; =20 kernel::pci_device_table!( PCI_TABLE, diff --git a/drivers/gpu/nova-core/fb/regs.rs b/drivers/gpu/nova-core/fb/re= gs.rs index b2ec02f584be..4296bef5f262 100644 --- a/drivers/gpu/nova-core/fb/regs.rs +++ b/drivers/gpu/nova-core/fb/regs.rs @@ -2,9 +2,13 @@ =20 use kernel::io::register; =20 +use crate::driver::NovaRegisters; + // PDISP =20 register! { + base: NovaRegisters; + pub(super) NV_PDISP_VGA_WORKSPACE_BASE(u32) @ 0x00625f04 { /// VGA workspace base address divided by 0x10000. 31:8 addr; diff --git a/drivers/gpu/nova-core/gsp/regs.rs b/drivers/gpu/nova-core/gsp/= regs.rs index a76dea3c3ab0..34ce8dd1f464 100644 --- a/drivers/gpu/nova-core/gsp/regs.rs +++ b/drivers/gpu/nova-core/gsp/regs.rs @@ -2,9 +2,13 @@ =20 use kernel::io::register; =20 +use crate::driver::NovaRegisters; + // PGSP =20 register! { + base: NovaRegisters; + pub(super) NV_PGSP_QUEUE_HEAD(u32) @ 0x00110c00 { 31:0 address; } diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs index 397124f245ee..f2aadeb429b8 100644 --- a/drivers/gpu/nova-core/regs.rs +++ b/drivers/gpu/nova-core/regs.rs @@ -13,7 +13,7 @@ }; =20 use crate::{ - driver::Bar0, + driver::{Bar0, NovaRegisters}, falcon::{ DmaTrfCmdSize, FalconCoreRev, @@ -37,6 +37,8 @@ // PMC =20 register! { + base: NovaRegisters; + /// Basic revision information about the GPU. pub(crate) NV_PMC_BOOT_0(u32) @ 0x00000000 { /// Lower bits of the architecture. @@ -108,6 +110,8 @@ fn fmt(&self, f: &mut kernel::fmt::Formatter<'_>) -> ke= rnel::fmt::Result { // PBUS =20 register! { + base: NovaRegisters; + pub(crate) NV_PBUS_SW_SCRATCH(u32)[64] @ 0x00001400 {} =20 /// Scratch register 0xe used as FRTS firmware error code. @@ -119,6 +123,8 @@ fn fmt(&self, f: &mut kernel::fmt::Formatter<'_>) -> ke= rnel::fmt::Result { // PFB =20 register! { + base: NovaRegisters; + /// Low bits of the physical system memory address used by the GPU to = perform sysmembar /// operations (see [`crate::fb::SysmemFlush`]). pub(crate) NV_PFB_NISO_FLUSH_SYSMEM_ADDR(u32) @ 0x00100c10 { @@ -154,6 +160,8 @@ fn fmt(&self, f: &mut kernel::fmt::Formatter<'_>) -> ke= rnel::fmt::Result { pub(crate) struct Hshub0Base(()); =20 register! { + base: NovaRegisters; + // GB10x sysmem flush registers, relative to the HSHUB0 base. GB10x ro= utes sysmembar // through a primary and an EG (egress) pair that must both be program= med to the same // address. Hardware ignores bits 7:0 of each LO register. The boot pa= th uses a fixed @@ -176,6 +184,8 @@ fn fmt(&self, f: &mut kernel::fmt::Formatter<'_>) -> ke= rnel::fmt::Result { } =20 register! { + base: NovaRegisters; + // GB20x FBHUB0 sysmem flush registers. Unlike the older // NV_PFB_NISO_FLUSH_SYSMEM_ADDR registers, which encode the address w= ith an // 8-bit right-shift, these take the raw address split into lower and = upper @@ -190,6 +200,8 @@ fn fmt(&self, f: &mut kernel::fmt::Formatter<'_>) -> ke= rnel::fmt::Result { } =20 register! { + base: NovaRegisters; + /// Low bits of the physical system memory address used by the GPU to = perform /// sysmembar operations on Hopper. /// @@ -253,6 +265,8 @@ pub(crate) fn is_wpr2_set(self) -> bool { // number. =20 register! { + base: NovaRegisters; + /// Boot Sequence Interface (BSI) register used to determine /// if GSP reload/resume has completed during the boot process. pub(crate) NV_PGC6_BSI_SECURE_SCRATCH_14(u32) @ 0x001180f8 { @@ -307,6 +321,8 @@ pub(crate) fn usable_fb_size(self) -> u64 { pub(crate) const NV_FUSE_OPT_FPF_SIZE: usize =3D 16; =20 register! { + base: NovaRegisters; + pub(crate) NV_FUSE_OPT_FPF_NVDEC_UCODE1_VERSION(u32)[NV_FUSE_OPT_FPF_S= IZE] @ 0x00824100 { 15:0 data =3D> u16; } @@ -323,6 +339,8 @@ pub(crate) fn usable_fb_size(self) -> u64 { // PFALCON =20 register! { + base: NovaRegisters; + pub(crate) NV_PFALCON_FALCON_IRQSCLR(u32) @ PFalconBase + 0x00000004 { 6:6 swgen0 =3D> bool; 4:4 halt =3D> bool; @@ -524,6 +542,8 @@ pub(crate) fn mem_scrubbing_done(self) -> bool { /* PFALCON2 */ =20 register! { + base: NovaRegisters; + pub(crate) NV_PFALCON2_FALCON_MOD_SEL(u32) @ PFalcon2Base + 0x00000180= { 7:0 algo ?=3D> FalconModSelAlgo; } @@ -546,6 +566,8 @@ pub(crate) fn mem_scrubbing_done(self) -> bool { // PRISCV =20 register! { + base: NovaRegisters; + /// RISC-V status register for debug (Turing and GA100 only). /// Reflects current RISC-V core status. pub(crate) NV_PRISCV_RISCV_CORE_SWITCH_RISCV_STATUS(u32) @ PFalcon2Bas= e + 0x00000240 { @@ -571,6 +593,8 @@ pub(crate) fn mem_scrubbing_done(self) -> bool { // These registers manage falcon EMEM communication queues. =20 register! { + base: NovaRegisters; + pub(crate) NV_PFSP_QUEUE_HEAD(u32)[8] @ 0x008f2c00 { 31:0 address =3D> u32; } @@ -594,9 +618,13 @@ pub(crate) fn mem_scrubbing_done(self) -> bool { pub(crate) mod gm107 { use kernel::io::register; =20 + use crate::driver::NovaRegisters; + // FUSE =20 register! { + base: NovaRegisters; + pub(crate) NV_FUSE_STATUS_OPT_DISPLAY(u32) @ 0x00021c04 { 0:0 display_disabled =3D> bool; } @@ -606,9 +634,13 @@ pub(crate) mod gm107 { pub(crate) mod ga100 { use kernel::io::register; =20 + use crate::driver::NovaRegisters; + // FUSE =20 register! { + base: NovaRegisters; + pub(crate) NV_FUSE_STATUS_OPT_DISPLAY(u32) @ 0x00820c04 { 0:0 display_disabled =3D> bool; } @@ -620,9 +652,13 @@ pub(crate) mod ga100 { pub(crate) mod gh100 { use kernel::io::register; =20 + use crate::driver::NovaRegisters; + // PTHERM =20 register! { + base: NovaRegisters; + pub(crate) NV_THERM_I2CS_SCRATCH(u32) @ 0x000200bc { 31:0 data; } @@ -637,9 +673,13 @@ pub(crate) mod gh100 { pub(crate) mod gb202 { use kernel::io::register; =20 + use crate::driver::NovaRegisters; + // PTHERM =20 register! { + base: NovaRegisters; + pub(crate) NV_THERM_I2CS_SCRATCH(u32) @ 0x00ad00bc { 31:0 data; } diff --git a/drivers/gpu/nova-core/vbios.rs b/drivers/gpu/nova-core/vbios.rs index c03650ee5226..9c214b9f4dd9 100644 --- a/drivers/gpu/nova-core/vbios.rs +++ b/drivers/gpu/nova-core/vbios.rs @@ -16,7 +16,10 @@ }; =20 use crate::{ - driver::Bar0, + driver::{ + Bar0, + NovaRegisters, // + }, firmware::{ fwsec::Bcrt30Rsa3kSignature, FalconUCodeDesc, @@ -92,12 +95,16 @@ impl<'a> VbiosIterator<'a> { fn rom_offset(dev: &device::Device, bar0: Bar0<'_>) -> Result { // IFR Header in VBIOS. register! { + base: NovaRegisters; + NV_PBUS_IFR_FMT_FIXED0(u32) @ 0x300000 { 31:0 signature; } } =20 register! { + base: NovaRegisters; + NV_PBUS_IFR_FMT_FIXED1(u32) @ 0x300004 { 30:16 fixed_data_size; 15:8 version =3D> u8; @@ -105,6 +112,8 @@ fn rom_offset(dev: &device::Device, bar0: Bar0<'_>) -> = Result { } =20 register! { + base: NovaRegisters; + NV_PBUS_IFR_FMT_FIXED2(u32) @ 0x300008 { 19:0 total_data_size; } --=20 2.54.0 From nobody Sat Jul 25 00:16:38 2026 Received: from CWXP265CU009.outbound.protection.outlook.com (mail-ukwestazon11021132.outbound.protection.outlook.com [52.101.100.132]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77EA138239C; Tue, 21 Jul 2026 16:54:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.100.132 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652885; cv=fail; b=lJnX49dhFv7r0a1b9J1GfA235xa5g3pz/Jp6uswPMECTmrCcS37/d6SQ5Lme/cmVxf0FZH84JQEQkcdvwpuXNszaFKKaCGgaNfA3brOYz+/yM4ruUYClNU95uxWIooSSOb8rt7Z4jNuA1BJs24Lgo9H4j0h0Dkbq5V+ccUljIso= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652885; c=relaxed/simple; bh=CVtl6QGHGHTgUxhd8Ee9uc5NPHuTrs9T/t3HWlWXORM=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=dvZyzn23pXVbmnPecL66X2w6VCTBMUW1OhZr6OBuBbJ3Yprxb+NWCLxk323xllsFY50ELummYRg5nmF/rz+2JDv7EpQ7sOErNoAEoBnJfoeNphZOvHkOOKY5bgy7BR120n2zK67DLU8e67/ICixsw8M7yZVBXa7D6g7bSmnsbpY= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net; spf=pass smtp.mailfrom=garyguo.net; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b=ocPpBmhq; arc=fail smtp.client-ip=52.101.100.132 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=garyguo.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b="ocPpBmhq" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=c3vYOu+qKYdz91Lub9OVxTiYc3s09uWLSJATZZuHS29IwwmS1+8pvHHrqV3T7Oj6yHQP4Nmm0fA75z7KMjvRSWOFJuFbypDHjH/0rdjpvY3Sm0c7mVOKITzLTd7kU7h2JztlEUR+vou+M8hIx6FwC/jV++fhnBORL2nUI9VTRdctjkQWQKbNsurdrYIjkrsMIhyilFy3Z2pDkuiDBsffhiNlCF0zFN1HoENvwYXYWL85YvwU/vN5ix0+jgiynPxL1+mN7N04WdVldoWpzO9EptMmoQFkqaJ4detHdE0B3vErBEz5sPrMNAtaoAXjN/oo5lDasfftEnbo0RlEIjl7Zw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=EH+Ks+rTkbtc+YjDCEWnOULQnHv8ONMCUfN815ETfyk=; b=aSXNce3dVqa0/7MIqtADvoAePNsVP8HKPAtXJdGZxagswyZLaT7wHAtcwZQ6orZ9nKLVVcHGq0Anbjk5ecpbHKj9lMimsjfT1WJSp+xCMrGZNcYRpMMUCj7aip1MEza1kSdX5Aww4SH3yzROdfibYNvDLojXGwE5abD/VhAzGQ6DH0MNB0D5sV1/7cF7ySPAlqblztcElyPJ6vCrJX5KQhU928ga+bEtn+vgDdOvaQpIEjkCTwwsMswcexnJIn0kGFvFErqbmAay0QxQ2EauXyg1yYi9L6RL3CeEGiCIzAnR2LmgH9IxBOjCBeS8ZxI2T8Nb0RF6jQ6G+9wZz/oJaQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=garyguo.net; dmarc=pass action=none header.from=garyguo.net; dkim=pass header.d=garyguo.net; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=garyguo.net; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=EH+Ks+rTkbtc+YjDCEWnOULQnHv8ONMCUfN815ETfyk=; b=ocPpBmhqlaZKodzrLDaDcUzAfQNhuU1jd3Zm0zpOkGAE7zcJgTq8nPFNH6UptUcFWNkUapq41bknAyYkO6NJ0zM7mIOt1E9aBa7nIhwVW9Z5wmPfwej96TqooAlkYDKC3FAo9CbfWBU/OCZ+sbslfVO0y8VLVCAoYcb8muyrJEk= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=garyguo.net; Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) by LO8P265MB7878.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:3ae::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Tue, 21 Jul 2026 16:54:34 +0000 Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986]) by LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986%4]) with mapi id 15.21.0223.017; Tue, 21 Jul 2026 16:54:34 +0000 From: Gary Guo Date: Tue, 21 Jul 2026 17:54:27 +0100 Subject: [PATCH 03/10] drm/tyr: specify base type for registers Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-typed_register-v1-3-452d72b60262@garyguo.net> References: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> In-Reply-To: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> To: Danilo Krummrich , Alice Ryhl , Daniel Almeida , Miguel Ojeda , Boqun Feng , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , David Airlie , Simona Vetter , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= Cc: driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, linux-pci@vger.kernel.org, Gary Guo X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784652872; l=6378; i=gary@garyguo.net; s=20221204; h=from:subject:message-id; bh=CVtl6QGHGHTgUxhd8Ee9uc5NPHuTrs9T/t3HWlWXORM=; b=BmQhSct2n/JjfcoI5g5rdOy8aqDhgeHB7HmT4ryN0SBg7rb2wUBKuHSw6XEmNLY4Avl2Vxj3f sse3W52DHj/B6Avb/lleTyzgDnVm212Xv5uQrdi5XuKm8htUqePwTn4 X-Developer-Key: i=gary@garyguo.net; a=ed25519; pk=vB3uIX95SM4eVrIqo1DWNWKDKD2xzB+yLLLr0yOPYMo= X-ClientProxiedBy: LO4P123CA0143.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:193::22) To LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LOVP265MB8871:EE_|LO8P265MB7878:EE_ X-MS-Office365-Filtering-Correlation-Id: 9250cad6-d9e2-483e-97cf-08dee748be24 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|7416014|10070799003|1800799024|366016|56012099006|10067099003|6133799003|3023799007|22082099003|18002099003|921020; X-Microsoft-Antispam-Message-Info: SqYb4db7u/nCZW5APDeKoEIl1VTsECpzJCAx9COBvak/4FFbMueosYuye7Ux086DtxvN6Ezsv+HRusvmJDQmFKEEpySSPxmwg9Px0CDcu0fDGeFlDoc1LcqlUtEb8yCuQiqoYauD+HeqXDiJEYVvnyL8ihPG6jtx7B1hwGxlScznMZiNPnwpytAX+CBscdMti+46KRTULWAd0VsncTZzcZN6bb+LA6fRrNslc11nebEzI/Ko7gkP17pYuT5V4gWJT5JZTkc1w0+hMsB6t8IeXoYs1Csm9L0K55mtSl1MLEakq2PI3yZMlrZ6vCmsLyLau1eXMB3M4q/au5ebjOw7tK53Aa/DlvVXVEs527fRgMwJoD3vS+ONrKojviG5b3X779RZ/5YN4E6s4L3ntPQjkxYGXSBerdhrPVjQRNIQqhYXJMPPTiJgTYGaudVEqRqHXKObPyth6yfSBH0k3okK8uVGoyNOGKBvYH/KN1S5IrH/Waf0JwHg4SI4QWNFgMtfVz/RFqD3D+iOXITVioSRTmgXrSuZTIs+muu7ZX0K3RPK+033Nw5albBgPjbIcLr4eCdq8cXWhnIruKPujA9/dVsgrw5/jvhhDwqx3Qz0qxtn66+kBodKcrUlDQbpv4zJRiAgrHYlAJo0UuYsx7zah/RYP5S8giYE3sPBHpEWiWRat8CN+oSa6rxcMnKUDJvio3Nxltw661mBMjXmSiU9vA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(376014)(7416014)(10070799003)(1800799024)(366016)(56012099006)(10067099003)(6133799003)(3023799007)(22082099003)(18002099003)(921020);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?UGtsbURBVWoxbXdhb1BkNnMxR0UxL3BGbUFvY3ByckFQU0NRL1pCU2RhbUdy?= =?utf-8?B?OXBocFN5UG1xbWh3ZERXNmhOY25hQVVCTmpncnNjM3R0NWJmRDNZWno3NHZO?= =?utf-8?B?ZTlWWlJ3M1hvd0tPMWJTcldicHQxZ3IzblN1bWJaK0FMRjZWUXZkNS85ckZE?= =?utf-8?B?Y3gzdXArOUh6bFAya1RuSFZhb1poQmZVdXhhYWRQK0s4dkxybnp0cmhzVXBk?= =?utf-8?B?VFRXMlFxVDh3eHpyKzRqeFBpa0NodmpXbVVVeXhjblhWU2twY3dTTmRLMnc1?= =?utf-8?B?SWd1L2NyL3pUT2JhRVdHRDREK051SVFvNk9ITklnK3VJbzVmSGZUVVVaTmd2?= =?utf-8?B?ZUVhdXRXQUhkRmh1OFVVbGVoemprSzJOUlhqelU1NmdiQWZNSzQzeS9ad0pn?= =?utf-8?B?dFhFSy9hek0wRHJHZklWS0FwWGhic01TbnFVK2ZwV3VTWW9yNGYvb2paT1Jv?= =?utf-8?B?ckk1MGxhL3JVbFFtKzdvWnlId0VGcXhJcWcwL0ZEaTJIWkQ1aUYzM0NXVnJp?= =?utf-8?B?U0V1Z0ZyRnRGL2w2S2drMCtwditPUE1nVSszSllBNG9ONEorUVk2bVRneFly?= =?utf-8?B?bk5lSzE0N2paaHJRRnc4VVNkeFRyZkQwQTAwNDFoYUR0bkVTYVpvc2tQMXp5?= =?utf-8?B?VEZQcVRPNEIvY3dPajRlVEZaRXNKaE9qQU9RWHVkYVNINDlqdnNhYnRpckZ3?= =?utf-8?B?N283QTNZZlpNeHdWd2tsUnA3TGtEdnl5eFdwbHJ5c0dOVDcyTjdLdEdtK1Nh?= =?utf-8?B?TTBNZTJVWTcvcGVuMFh4VWRWVitQUjYvclhNY09rNFA1d0hMK3A1cVMwdGI0?= =?utf-8?B?eTM0ektEQ2xNNDl1aGZHVDdPc3BHTzdaRDFYeVhEUU9BVmQwaFkrM0pjaFVK?= =?utf-8?B?a2VJQ0hzZGtabzcvdjJBa1Ezczk1VHhOSFE4K0JueTBKTjNCaWFwR01qcktI?= =?utf-8?B?UHRzRjBqajV3VGVkVFI1R2hSR0tpRWp3L0F6eFowbmxJV2hLQ1NMbVAzKy9w?= =?utf-8?B?Sno2aWw5dVI5ZGlzV2N4WW5IRGhxd1p5VTRsMUl5cHNVVzFLcnBWakhIRmJw?= =?utf-8?B?M09wWk1TbURqYW5oblIyc0cwVW9CbzY0V2xVam5ZNm4zdW5zemJETWt5QjZQ?= =?utf-8?B?ejVIVlBnd1MzeldtUHhzZlNVNTFhbFZIZ0R6MkdPYkpSRlFIV09KM3VqVkxl?= =?utf-8?B?MUxLaGJBSWp1TzdDREFKUHNzUnNYN0lKTi9iOCtYKzExWU1keFBwK3JCcCtE?= =?utf-8?B?SU1rWGRPdG5LZnhvb3RMT2wvdURDdVYvU240Zng2eVF4S2lnUUJvSExGdEdC?= =?utf-8?B?R21CMU5iWEc1dEdreHFoRXpOb1h4R2wyc2k2TEw1dHpacC9kOGVPVWRQSTBN?= =?utf-8?B?YlhkcHlhbDd5MXpCZmlrRFUvREdWRDBDRG8yc0pqK2pwN0NLWjgwRmhlTGh1?= =?utf-8?B?dmZjUzlkNDRzOGdCU212VmgyaXVXdmdJa1UvOXRNdlBYVVFFcERIWG15RHpn?= =?utf-8?B?WWNDVmlJUlRPUnVvNnNQK2JvUTU1MVR1WkI2QWhpRTEza3o1WFJ3dWIyT2xM?= =?utf-8?B?QjZRWkM2MVR3WjluMGthd29uOTdqTFdFc09DNER3MS9xMURVSkNFaTB3Tkpt?= =?utf-8?B?a1EwS29WSDRwNk9ES0JoZzhPNGoySW9FRjdOZy9CeGxpOWNKMnJSdDhKaFRr?= =?utf-8?B?Uzhsb05hTWs3cEY1S0NiTitnclFWZ2JZdkY4aWdGNTlBOFg4d3BkZDBwTHRs?= =?utf-8?B?Nlo3a3dIVHRFYU5oVWNDSm9Pb2xmaDMvOXRQTmd3U1NteWEvRHh5VnNaangz?= =?utf-8?B?c1I4Zy9nUUpBTnNING9kVTJRaE92SDlTRUpkYjZMQVNxU2E5V1NCNWRZd0d5?= =?utf-8?B?cVlaZFhOZU4ydzdyMUNSNlkyYlJaajBOYytmVzlvSG1WQkdHdUJTZXptVzlh?= =?utf-8?B?d3lCUXpTSk5LWEJtSDVvZmhVbUkyWFVaZXIxWXBGeUZiNzdiWEVUanArMnRi?= =?utf-8?B?UGpVT2Z3bElQK2VTR3hKT2pBREhKaXhJZlhtTjEybFlxbDJva0gzNlhqMi9D?= =?utf-8?B?SWxjeWM1TkhHOW1DSU9aQVExQnAxME1HaTBneThxMDh5aEtCZTZDUGZTN1VJ?= =?utf-8?B?OWlYdnBxVngrNVFaKzBQSEVSZytnR2ljUkZJNlgzY0hVLzRLanJMWldtcnN6?= =?utf-8?B?RjZDbklMdmszQ1E0UEFwemcrbk1ueng1dVJVVlN0VWVWRE1zSHlid1VzRlg2?= =?utf-8?B?QlNpZ1hWb1hrY3FCNlhpZzFLamd1cEc4enAvTmlQWThQaXVYMUh0RHAvV2Nq?= =?utf-8?B?NmsyZFFvaWFTbGdjNys2WlVIUGRZWUNTY0RXVlhBdW80dVF0Y0dEZz09?= X-OriginatorOrg: garyguo.net X-MS-Exchange-CrossTenant-Network-Message-Id: 9250cad6-d9e2-483e-97cf-08dee748be24 X-MS-Exchange-CrossTenant-AuthSource: LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jul 2026 16:54:34.7714 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bbc898ad-b10f-4e10-8552-d9377b823d45 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: wIpHJY1Txrh6tbn+/81yyTJ9zR2GAL6uXrKZFsQ1BSP/19AU63BEF5123LFZlHlrJ7I14RjlZC9ysXoJkT1WEA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LO8P265MB7878 All registers use the same base type, which is `::Target`. Thus add the base parameter to `register!` invocation. Signed-off-by: Gary Guo --- drivers/gpu/drm/tyr/driver.rs | 1 + drivers/gpu/drm/tyr/regs.rs | 42 +++++++++++++++++++++++++++++++++++++++= +++ 2 files changed, 43 insertions(+) diff --git a/drivers/gpu/drm/tyr/driver.rs b/drivers/gpu/drm/tyr/driver.rs index 8348c6cd3929..401a4b321eaf 100644 --- a/drivers/gpu/drm/tyr/driver.rs +++ b/drivers/gpu/drm/tyr/driver.rs @@ -43,6 +43,7 @@ }; =20 pub(crate) type IoMem<'a> =3D kernel::io::mem::IoMem<'a, SZ_2M>; +pub(crate) type TyrRegisters =3D kernel::io::Region; =20 pub(crate) struct TyrDrmDriver; =20 diff --git a/drivers/gpu/drm/tyr/regs.rs b/drivers/gpu/drm/tyr/regs.rs index 831357a8ef87..ef21d90dbbc4 100644 --- a/drivers/gpu/drm/tyr/regs.rs +++ b/drivers/gpu/drm/tyr/regs.rs @@ -55,7 +55,11 @@ pub(crate) mod gpu_control { uapi, // }; =20 + use crate::driver::TyrRegisters; + register! { + base: TyrRegisters; + /// GPU identification register. pub(crate) GPU_ID(u32) @ 0x0 { /// Status of the GPU release. @@ -313,6 +317,8 @@ fn from(mode: FlushMode) -> Self { } =20 register! { + base: TyrRegisters; + /// GPU command register. /// /// Use the constructor methods to create commands: @@ -378,6 +384,8 @@ pub(crate) fn clear_fault() -> Self { } =20 register! { + base: TyrRegisters; + /// GPU status register. Read only. pub(crate) GPU_STATUS(u32) @ 0x34 { /// GPU active, a 1-bit boolean flag. @@ -461,6 +469,8 @@ fn from(access: AccessType) -> Self { } =20 register! { + base: TyrRegisters; + /// GPU fault status register. Read only. pub(crate) GPU_FAULTSTATUS(u32) @ 0x3c { /// Exception type. @@ -766,6 +776,8 @@ fn from(mode: CoherencyMode) -> Self { } =20 register! { + base: TyrRegisters; + /// Coherency enable. An index of which coherency protocols should= be used. /// This register only selects the protocol for coherency messages= on the /// interconnect. This is not to enable or disable coherency contr= olled by MMU. @@ -806,6 +818,8 @@ fn from(mode: McuControlMode) -> Self { } =20 register! { + base: TyrRegisters; + /// MCU control. pub(crate) MCU_CONTROL(u32) @ 0x700 { /// Request MCU state change. @@ -847,6 +861,8 @@ fn from(status: McuStatus) -> Self { } =20 register! { + base: TyrRegisters; + /// MCU status. Read only. pub(crate) MCU_STATUS(u32) @ 0x704 { /// Read current state of MCU. @@ -860,7 +876,11 @@ fn from(status: McuStatus) -> Self { pub(crate) mod job_control { use kernel::register; =20 + use crate::driver::TyrRegisters; + register! { + base: TyrRegisters; + /// Raw status of job interrupts. /// /// Write to this register to trigger these interrupts. @@ -910,7 +930,11 @@ pub(crate) mod job_control { pub(crate) mod mmu_control { use kernel::register; =20 + use crate::driver::TyrRegisters; + register! { + base: TyrRegisters; + /// IRQ sources raw status. /// /// This register contains the raw unmasked interrupt sources for = MMU status and exception @@ -965,6 +989,8 @@ pub(crate) mod mmu_as_control { register, // }; =20 + use crate::driver::TyrRegisters; + /// Maximum number of hardware address space slots. /// The actual number of slots available is usually lower. pub(crate) const MAX_AS: usize =3D 16; @@ -973,6 +999,8 @@ pub(crate) mod mmu_as_control { const STRIDE: usize =3D 0x40; =20 register! { + base: TyrRegisters; + /// Translation table base address. A 64-bit pointer. /// /// This field contains the address of the top level of a tran= slation table structure. @@ -1100,6 +1128,8 @@ fn from(val: MemoryType) -> Self { } =20 register! { + base: TyrRegisters; + /// Stage 1 memory attributes (8-bit bitfield). /// /// This is not an actual register, but a bitfield definition = used by the MEMATTR @@ -1133,6 +1163,8 @@ fn from(val: MMU_MEMATTR_STAGE1) -> Self { } =20 register! { + base: TyrRegisters; + /// Memory attributes. /// /// Each address space can configure up to 8 different memory = attribute profiles. @@ -1220,6 +1252,8 @@ fn from(cmd: MmuCommand) -> Self { } =20 register! { + base: TyrRegisters; + /// MMU command register for each address space. Write only. pub(crate) COMMAND(u32)[MAX_AS, stride =3D STRIDE] @ 0x2418 { 7:0 command ?=3D> MmuCommand; @@ -1347,6 +1381,8 @@ fn from(access: MmuAccessType) -> Self { } =20 register! { + base: TyrRegisters; + /// Fault status register for each address space. Read only. pub(crate) FAULTSTATUS(u32)[MAX_AS, stride =3D STRIDE] @ 0x241= c { /// Exception type. @@ -1572,6 +1608,8 @@ fn from(sh: PtwShareability) -> Self { } =20 register! { + base: TyrRegisters; + /// Translation configuration and control. pub(crate) TRANSCFG(u64)[MAX_AS, stride =3D STRIDE] @ 0x2430 { /// Address space mode. @@ -1627,6 +1665,8 @@ fn from(sh: PtwShareability) -> Self { pub(crate) mod doorbell_block { use kernel::register; =20 + use crate::driver::TyrRegisters; + /// Number of doorbells available. pub(crate) const NUM_DOORBELLS: usize =3D 64; =20 @@ -1637,6 +1677,8 @@ pub(crate) mod doorbell_block { const STRIDE: usize =3D 0x10000; =20 register! { + base: TyrRegisters; + /// Doorbell request register. Write-only. pub(crate) DOORBELL(u32)[NUM_DOORBELLS, stride =3D STRIDE] @ 0x800= 00 { /// Doorbell set. Writing 1 triggers the doorbell. --=20 2.54.0 From nobody Sat Jul 25 00:16:38 2026 Received: from LO3P265CU004.outbound.protection.outlook.com (mail-uksouthazon11020086.outbound.protection.outlook.com [52.101.196.86]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C1074384CC4; Tue, 21 Jul 2026 16:54:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.196.86 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652886; cv=fail; b=GA+5cwp4/g1mO5E0yJLaT8rPvz/dJMEUBEo3EJ7pExGcYpNKsjm9BP+zhp5TU0WSEGnITYdDl8NOUkszZrnI/okFjBX/M8XoDMIyQJfOsfUPixhk/9xthr5BI+0quYjhqjVOz/mcEY9mXi3dhcudRKPgpk8Vvhkzh9/AxjX15LI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652886; c=relaxed/simple; bh=ytBzPDgdYHcUQOkTvpajw+z5xUNMQfhuUYLGbkFxHXM=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=Sc3NMK7xQjkba6Q2VlkAeiXi1jVn+/Mfk4uH3IVbQQXs1/abfa+kRgowSbfO/VgcXAnn1GBKBQ1w0J2oe6/bHy8a4+LTL/gI89TaqeYXtaatLKYhBEtaAE7N7yY0xFHsF8LcFWUCQPpw2S1hO/Z9MUPh7dsFG1tIvs+0mVZUqmA= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net; spf=pass smtp.mailfrom=garyguo.net; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b=K+oqBW1l; arc=fail smtp.client-ip=52.101.196.86 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=garyguo.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b="K+oqBW1l" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=xfU7jdiDINk8s71tmX3XAOrF+AaJ908uoVqA2f/qEyF9wEvz8el95qCsfpWk/okVgShEGrgV0D0ZxzcAK1g/mWF+Hia2vO6o0YZS6BRdX5qhzu6kJ183QfxRe2EcWZ7sO06YPFN0x8SazeXQ6oEKNjJ22aYWoz2ETmTuS0sRWaXhoh5rPFSNGNhRaRESdlom4dovXnHsmlstqbYP/1YJ3CG0u6menOJ0L4lVBz0NdW/HUTFhyGub3A0jEBsGyr1W9RcTELXl0LIVX+Ew2sEj25nEGGvRtjnXbH80JYKBfOy0y9tgk2tqOTjl/vbPTzmVVkMM85mPghxSoYBzxAgMKA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=cRuRGmh3FNrrueS8zDRFfCMFsMLyRDvXKrzBaZk+Ups=; b=YPfM7OBf58ApesegJlHFkOTUZJ4AJEqMLBCHM3mbh+vXrR9+Yko/UcR23WnmJxW8v0W1/L89MWlhA1WC4a7RbIyoL3+gLexC0bPeAtWg/4u3jicfYMDsnIrPwOyHKlwigSQKgxMH5mkhgA9sljP421TNtaN0XTuWMRChIUK5JJ+N3NpZYj3tTS7CdxC5HqVbBGHYUKW2UiRWZkwsFQ4lXjCABUi5qvqhQLWfj2OWp8ILFmAvG19IXaknmWE6upLVnH/SITgJ2j06BCl5mnwRGAifeLmfmC5G2O43ttI310WO0QuvnkSa7e/w2FXDbskVjGCBH8zz+ztZIFNHKHlzYg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=garyguo.net; dmarc=pass action=none header.from=garyguo.net; dkim=pass header.d=garyguo.net; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=garyguo.net; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=cRuRGmh3FNrrueS8zDRFfCMFsMLyRDvXKrzBaZk+Ups=; b=K+oqBW1ltg7dD6Ugbe1Ml6QCEGft/a77qBo4yoChLXMsxfrzBs8Mw4BspeELZ2AdN5IlghyPflA1oUz6bMAres8l9x+4mwZV6Gi8eVjmxd8fCFwe3DBmJrjCQbdl1jJ9e78Nn16lNjX13Nq74xLrZt7rFn3jn33n6OuwAz9TSfA= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=garyguo.net; Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) by LO8P265MB7878.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:3ae::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Tue, 21 Jul 2026 16:54:35 +0000 Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986]) by LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986%4]) with mapi id 15.21.0223.017; Tue, 21 Jul 2026 16:54:35 +0000 From: Gary Guo Date: Tue, 21 Jul 2026 17:54:28 +0100 Subject: [PATCH 04/10] samples: rust: pci: specify base type for registers Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-typed_register-v1-4-452d72b60262@garyguo.net> References: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> In-Reply-To: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> To: Danilo Krummrich , Alice Ryhl , Daniel Almeida , Miguel Ojeda , Boqun Feng , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , David Airlie , Simona Vetter , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= Cc: driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, linux-pci@vger.kernel.org, Gary Guo X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784652872; l=939; i=gary@garyguo.net; s=20221204; h=from:subject:message-id; bh=ytBzPDgdYHcUQOkTvpajw+z5xUNMQfhuUYLGbkFxHXM=; b=rmXDNCGb/KrRf7Ve9/BOxFBd9Zzp8D/pwYjt1iFN4MAr4y+0uaEMGfUlFkEqZTLOIlEz5tcBC 4VvNpaP5PwADli0Kb1vevJdzojvFkO/y7Y1XeX/Z78DtvnMNA+a+krs X-Developer-Key: i=gary@garyguo.net; a=ed25519; pk=vB3uIX95SM4eVrIqo1DWNWKDKD2xzB+yLLLr0yOPYMo= X-ClientProxiedBy: LO4P123CA0143.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:193::22) To LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LOVP265MB8871:EE_|LO8P265MB7878:EE_ X-MS-Office365-Filtering-Correlation-Id: b404e02f-9837-4a9c-607d-08dee748be7b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|7416014|10070799003|1800799024|366016|56012099006|10067099003|6133799003|22082099003|18002099003|921020; X-Microsoft-Antispam-Message-Info: xMrJ9oNuO6QCFk9iNNa5lcd5uuL5f+I2MRgbPIVA2L7Rk6sgtrDnq9Tn20rW+mGu8W/aOls3Qj74yaS6eKXDbB8j6w0MBtpKe84c9Dx57oOgS6Q69ydMFF7iQO5uPpzpccbWV9Tokd8ITUtQkA5bLSgG9DAaqrkTQUONKkNTsyVQBNJzJOt2iM3elG7jzAxJCmqbV/TZNVcqoG+WrFhdpf+e15O8+QiO4DIlS639HI20lGBcwaMG/5dPX2Fa620H+uf8eygd84SS+GtXut1tjDXuK86ra7JgrMuXgnlsSisrwpy71gh4Mpn5gsOq4lVGgGNVpFTcwOTCyXuusxq8NAjPrTY0G/GGCLNJhYe3/z+qFDrC+sgEaZ/s8hBN+FBcP3xlQ85KfPIlY/wRbIwQR2Mzz+lV3pDZiiuFMfDLL6bEFahy+XrS0TOa2L2i5bahFkpaVlCr8hq2Fy5Pa0dOMTx1QaxThwmI7S0bO55G96uYuBOWhUnUQIckt53rayzCm+1ga0KwObJO7TB7yOvqcrtGSqsWZA1fHmdaLSiPFguHJ3zH1AVbmAhDlfb2nZEC52/tyc3tD6SPMXWg2Be9/LDZD/quDn4pUiy1UZORpDCPAXZZ4OIrbTDmPWU4MpaOrqk1Hig4joLTbw4P7iLKxp/GjaCbXdGS+EZMVDLyo7NeAVpcuuJFcTtZBCWHx+EheXUPJUHldoSkdhShGlehXA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(376014)(7416014)(10070799003)(1800799024)(366016)(56012099006)(10067099003)(6133799003)(22082099003)(18002099003)(921020);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?bkhCd2ZqcTVPR0FXQXNTdUNkOS9QS3FFK25mbk9QTjhDZ1luMlovVU9KTk5k?= =?utf-8?B?SktQdkcyalc1aHRmaUFWUXNIcHhxVUVBSHZJN25HWHVKOEpWVmxueEJuekhC?= =?utf-8?B?RmQyc1B1bHE0cTQyZ2FWRCtGekFEWWlVTTM4TGN1ZlhZTXVoWGJpdi9mVVNa?= =?utf-8?B?M0VGSldQcm5aVlZVdlZTNGdsZWRUUy9xY3hBRzdzZGVoMURpZkFsT3d6ZUNM?= =?utf-8?B?a0JjTDJOY29ydnZqSUxOVGwxNTNuTWdLa2o3b28zeTh2SjNPL29UbVJvcDly?= =?utf-8?B?THJuOTd3cjBTK3B0dFVqZWlrWitNU1ZVT3I1T0FiNkxydVFvNFlaSHRxaWlv?= =?utf-8?B?Z1lrc05UREk4MkdGTzl5VHVGUGZGNTBVWSs2VGI0YjV2VHBiTHlyMjUydTBy?= =?utf-8?B?OE41Y3ZyVjZwUi90OVBxS0hrWWZjenZ3RXRSdFdUZmtzZEYxMzZjTGM0ZWxq?= =?utf-8?B?NGhNN1ZZKzZTcjJYYTNsYzl0aTNNK1d6TVBIa21Scit3aUtuU3lpQlljK1Iz?= =?utf-8?B?YWN3aFA0cEFnb2ExVUVLbkRpN1FyRG5uOVRJWVdaRmpoR1F1VE05U3d6OGtT?= =?utf-8?B?RHZpTWRrVk5HRlFMYm9jT09LZUh1Z3ZkZFFQRURTU3JkTlYyV2tjRkNOTk80?= =?utf-8?B?MzBGUUZQK3ZaVWZkUDdwMmJxUmxrQU5Yd29Cc3RVcG8yNmVmby9MSy9YYkFT?= =?utf-8?B?OHBFYkNsSFFQaWR5dktzdnphZU9VUk9JYll0c2xxNmhOQkVGNWpnbHMvU0I3?= =?utf-8?B?dU5EeWpBZFFlVERucmt1ZzljOXhYZWJmSng4R1JtSjBhNytHdGErVjczbUgx?= =?utf-8?B?UzRGOVpLeGdXZUN2L0RFN0owenhmZ0hjWUJERzJuYXFzMktOc29OSHIxempW?= =?utf-8?B?cFNnQStoNEdWYXhGNjNCM1RDakF2TjV3SlFXWURnWlpORWo1YjcxQU9qb0Jz?= =?utf-8?B?d0laeGZDRU4zL09VaCtJMTl1Mm9MVFBoVWRyWWd4Zk10QU5kZFlzNFBaNVRY?= =?utf-8?B?ZnF2WkQzQWN5aWR5RlZLSXhmRDhjcDlXbHZaYzF2dGFZZTZWL2pNc1p3Vy85?= =?utf-8?B?MndBZTBqM3cycUJPdlg1emxmQ1NZdWJhb1JLUm1yMXBrNXFoREQxRnplZGpL?= =?utf-8?B?Q1NQMndZQmdrcTM0QjM3Rk04VTJOZlMrejQ0aW04M2lXOC8xNzArTjEwVDE5?= =?utf-8?B?NDdzWUJ5Um8yM0UzdmRRM25kS1dTRXBpR0NBbU5OTzh2MVB3VjBWRjhoVWNi?= =?utf-8?B?VDZMQnhTdEY4clE0UGhzc01MOExsZmdJNm8xM3ZvYWcwNGtWQllmbXVPanoy?= =?utf-8?B?cVEyRDdyZUdxMjhQeUNaeWpZckFCbW8zMjBsTUk3aXF1eFFwcHFjVHdEcEJi?= =?utf-8?B?Vnh4cjFSTHplc1dOU3VRbUc1SzBEVnZXTlRDN2tuOExVV1hZYldxYTRKa2Ir?= =?utf-8?B?WXkyWTVaOStXelY2RzJ3MmFRc0ZZTXRWSkNyZkVhOWxFWDE2SlR3eWhUUEZu?= =?utf-8?B?aUc4VDE2VWxIdDQ1aURiZzM0SVJHcWZKNkhEcXA3UFF1YkV6cFF0VlFHODdy?= =?utf-8?B?bUY5ZjM1M0syaS9mVCsxNmNjQ2VweUNHUDkveFltMEVTOXp6MHBmZU5ITXJr?= =?utf-8?B?RGRSeTNCbGxBNFRZWHh4NzJyck9CdXVXMkZwQy9wYXl1OXo1d0JtKzRETzFC?= =?utf-8?B?bFhBeEJnWDk5a21PZE5uNWsyUGYvTUY3b0h0N3lQaXJuRWlWVGFoQklrR3VC?= =?utf-8?B?QlVOT0Z3NzJ6eTlqL3FKbGNGZitZdWxVNi9TU1lVQTg2eG9iVGNOS2NXMTRX?= =?utf-8?B?TFBEdFpBNkZDWmlEYkxmaHd4M3phMGcvT0dQTWFkYndzNC9YWUhHc1ZXUTVF?= =?utf-8?B?a0F1Q0l0VTJWSnpyaWV4WXY5UnlLK3hWSDVEZWhLaGxCMU9MN0VDM2RQem9m?= =?utf-8?B?THBSaUZhTWlYQVFMeWV5YWlzRURoVjZidXhSaW1PbHNSdVUyUnp4QnFLMkRK?= =?utf-8?B?Y3QwMDZycVFlYkhXTk02WTdEUlNVSi9vOTdpVjBqL1NMaWZ1Sy80dHZlRXJi?= =?utf-8?B?bXRESlVJMVZRZkU0UFp4U2NaMnppbWpoZk5xVFlDQWZmRnkxNklwWjFvd2Fn?= =?utf-8?B?bE9BVDVWaVVIeTNMcVEwMkozemZYYlJQMStqT0MvYWxkTjY4ZktRY3JPWmZU?= =?utf-8?B?NDV1ZjM3QncyN2tJdWhPVUV3OWE4VU5JcU9aUFFOKzdQU1dWa0E3TVJ0aDBh?= =?utf-8?B?Qld1Wk1Sc0dic3JGUEZ1M1pnWVpmSHVHcng5VFl4Yys1aGRPaHNXaFo2bWRI?= =?utf-8?B?RlZGN1VDa3JhM0VaN1d1N09rTEg0NGhpNlJYUkpYUENrNTJha1Aydz09?= X-OriginatorOrg: garyguo.net X-MS-Exchange-CrossTenant-Network-Message-Id: b404e02f-9837-4a9c-607d-08dee748be7b X-MS-Exchange-CrossTenant-AuthSource: LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jul 2026 16:54:35.3166 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bbc898ad-b10f-4e10-8552-d9377b823d45 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: yX6helg3OV9YGkKStzR8ZtUHkWdp/J3QHIUjguQjiW/xMLo93FhCL421dTbPlY1M2a4WwNE/w+CP7/utJLdR/w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LO8P265MB7878 The `register!` macro is going to require explicit base type, specify it for both `register!` usages in PCI sample driver. Signed-off-by: Gary Guo --- samples/rust/rust_driver_pci.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci= .rs index 1aa8197d8698..aca8af795785 100644 --- a/samples/rust/rust_driver_pci.rs +++ b/samples/rust/rust_driver_pci.rs @@ -23,6 +23,8 @@ mod regs { use super::*; =20 register! { + base: kernel::io::Region; + pub(super) TEST(u8) @ 0x0 { 7:0 index =3D> TestIndex; } @@ -103,6 +105,8 @@ fn config_space(pdev: &pci::Device) { =20 // Some PCI configuration space registers. register! { + base: pci::Normal; + VENDOR_ID(u16) @ 0x0 { 15:0 vendor_id; } --=20 2.54.0 From nobody Sat Jul 25 00:16:38 2026 Received: from CWXP265CU009.outbound.protection.outlook.com (mail-ukwestazon11021132.outbound.protection.outlook.com [52.101.100.132]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 937E3386C0A; Tue, 21 Jul 2026 16:54:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.100.132 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652888; cv=fail; b=IvapuqAaCe65iDP0dWSo2qaaCGBg/p6m/znVkcTrOzEsAmECvywDzizzeRi04Ri1E5edb1qPwBM9JANlukK9McxTi44hnaE84J/S8wpoTCHxxxd2JYaiQJ3xL8tvHZ/QEvwmWhec6P44LTooDni1b936NCZByHUwfcg0mmOFJQI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652888; c=relaxed/simple; bh=/tbPMm7MZEGr2hdg4hsZfc5XlLdU+1m/iS/d5okVeRs=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=dbc38Hv5DyjVZrY7jonjKH5hRJZA2sowVK+n44Qaz7sT7/XZexikvHb4Tpor06oRCukrQuzvPJunzASCW+Dgne3qjpQlb1AmbbvvU449lRVuHQuZNxixY7dfh15Hue5Qj+XT8EmGtuDayvos45Ln8hWZVBQOoW1Dgwy5pK1yX9k= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net; spf=pass smtp.mailfrom=garyguo.net; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b=xU3l24Nu; arc=fail smtp.client-ip=52.101.100.132 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=garyguo.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b="xU3l24Nu" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=YD/z8qafj8w6WK+6ODxL/9beE3hIrwGg5M9lOeGdoY2f9I/S5l+QiN1O08FJ6exF3slW7xsB3b2yvSrPJ1+mvnLx96PPL1fEMtgxDGmWBmUwzkMDtHS669fEwncyRVumcSvdAjYNlTB+CscGudNCbMoiWFHVzGVdQzFc0puroYfo7S+Kt/s4jgDvacE+x4vGn/fKpW6ey+CcmUbsDjvKLcY5vM31pDa8Q5DWRFYCEE383c5oexvcKvO28FXFxFcKyir0wUFjxxSqKE/zP7XZRPJbVHuUf0GWaGNbGnF0VDt9vu7xb3pTKmsLipzF9to0/suHZsTj3ax/k8N3s9/YSg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=pqvt61eNCMhTn8pEzy/jGP0FdJQ7M057SVVhboqWcpI=; b=sQaNcXWkVpKXSYwx8IIa9N3KWUF5pO0K3PKjhWWy7yiDQOfUj/+DlSCWUBurEpEHKC/LvuFk5BeKz3eqKqLa7xg6VNxn97nBUGvkdypZ/6VLYGGuKS+KRAxizk1g01/qFC9zRmvz8W93sQRDk9L4r/cyWBNFYMB/3BTZ1cmMeS4ak4NDkZ+rGAaQsbI/MzYTS7FF31m+t1PwCVEX/UjHzYcyFwQ2JJWyntKanUTryBmSL7McpaV/RX3xFLqX86gR2DdQls7FdZhWswRVsyZnhPKzZXqh89p9xUrttiLPfMaRnK8Lrqfk5ztWn6VhTAoc6JXoxTK1vBfFgDjrdxRgdA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=garyguo.net; dmarc=pass action=none header.from=garyguo.net; dkim=pass header.d=garyguo.net; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=garyguo.net; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=pqvt61eNCMhTn8pEzy/jGP0FdJQ7M057SVVhboqWcpI=; b=xU3l24Nu8ATRmjPb0BNxXzBvSxRImv2Zu93weD44ES18swVLPkx8+WFIjiwxPCNuWGx6V9o2WhktYxq7gMwp+GtdYmkaUUt4boU/mEDVGXThC+7Hqy4Nk9W7Gk9zC5RRPhM4bfCUjakaZQIFvD3+vnYCJ5GwftI57/QESf8CxRo= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=garyguo.net; Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) by LO8P265MB7878.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:3ae::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Tue, 21 Jul 2026 16:54:35 +0000 Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986]) by LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986%4]) with mapi id 15.21.0223.017; Tue, 21 Jul 2026 16:54:35 +0000 From: Gary Guo Date: Tue, 21 Jul 2026 17:54:29 +0100 Subject: [PATCH 05/10] rust: io: register: make register have a typed base Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-typed_register-v1-5-452d72b60262@garyguo.net> References: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> In-Reply-To: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> To: Danilo Krummrich , Alice Ryhl , Daniel Almeida , Miguel Ojeda , Boqun Feng , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , David Airlie , Simona Vetter , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= Cc: driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, linux-pci@vger.kernel.org, Gary Guo X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784652872; l=13356; i=gary@garyguo.net; s=20221204; h=from:subject:message-id; bh=/tbPMm7MZEGr2hdg4hsZfc5XlLdU+1m/iS/d5okVeRs=; b=dC6R3tnbzA8WfUd7G6E8uIHh7G0cPg5LGaLQC/bdZO6ph302S/Kwy6h73pwAKAhMm6tSk9Kj9 X7tz1z0nH4ZARTnXXqYT1U6mMZVchRdq2w98Y/roGJSBNdeA1a20zRt X-Developer-Key: i=gary@garyguo.net; a=ed25519; pk=vB3uIX95SM4eVrIqo1DWNWKDKD2xzB+yLLLr0yOPYMo= X-ClientProxiedBy: LO4P123CA0143.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:193::22) To LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LOVP265MB8871:EE_|LO8P265MB7878:EE_ X-MS-Office365-Filtering-Correlation-Id: 48b3b6b3-18f4-4be2-5aa0-08dee748bec9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|7416014|10070799003|1800799024|366016|56012099006|10067099003|22082099003|18002099003|921020; X-Microsoft-Antispam-Message-Info: AvAHAuTRiKesMwSfDnRjS/G39PBN7eAAmE1suKgXXWAnUvAusK3Og76N4vkoy12PS0sr0GXXeQrG9PLRAn8Ft/WWduVCp5vMe355l48/yESrnZsukqjS7TJL5890D5kndWopZHMajFHgz1SVrkWWeHjdAxRTrOpvX76u6ddzoiRapOMBvLnR176a/bbOEaht2i0DXkfcswSM89ohrR9vxDuqzL/+cKZ1VUejCrFY7oiPVDLlcxr9NgUE55sJFK8Rs2tYFD/4PWC3Y65zvHT6TmJiC3yev470sy6gBlgsnoCA+lrpqpl8YFInmfMyxZUcMzDpLWhVn0QvK1FdW+BQyeZKWVUIOSTotaVp6wt+VO/g8EJq6+2e0E7uTjZOmwa/uFoeqdfvevTs6/9yFhZpjczAupNKfERk7uGSo5jfJXzTVuqEOmJVhlRE/btzoLpPpIEnxC4ERCtj/zQh5rokIKhIviPOhwF9IoKKmsrSohmg0ZWildZZ+N8X/eV8bUMXKuE+lXxJ4km7lkbthnqHXVlN/ShIt2w+oqe9oHEK6EgRWJnwvp6zzHtAiQQKL6fJvIpVM9Ep7hMl4z8xW3mELFqPZB2Ee0uqqJ1R6LaUFgCUiuNHih5lxc9lrZxDHcALJh7Cbl+fkgObJEfaLs1O1P9gkYRFjOdXBHbGWbSumyIMTbzAcFIpI4Ef+g+kULQQuS/fOxwBrez+LMpiZFl6/Q== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(376014)(7416014)(10070799003)(1800799024)(366016)(56012099006)(10067099003)(22082099003)(18002099003)(921020);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?Rm5YV2VkeGdNZzRYNlVWbTlyMk13djNGYW4xNkJCUjEvWWNNcysrK0JUZXpR?= =?utf-8?B?Y1A5NmxLSzhVQ2dJK3NYMUpSdjgyQ2hGZHR2UFE3N1RjK25NcEFtQnhhU1ZL?= =?utf-8?B?NXZWTkJpSi9hNlRlUitFd3F2SDViVXAwTUtFdzhmU28wRnM0aGJNWU1QcnRN?= =?utf-8?B?OFRJVTl5eVB6alJMZHNqZ3BwczZWT0FCb3NTVmhZZEVFZjZKVUo3WDRTaVZQ?= =?utf-8?B?VDFoc2l5MDZBdFk5T2lIUVFVL0FsdHJjdTZaaFBzeDM4SGtLV2hDclZKOHVj?= =?utf-8?B?bEFFV2lPWWRDSFJvTWZkQk5JbnM2NHR1SFlZaFBheXdnTTJkTHBPSjNPNFll?= =?utf-8?B?SWdjdHZ6M3c5QjMxMGoxRGtIeEdjWHNrU0ZQV2JPUFpoZzQyc0hMVlBDbFZY?= =?utf-8?B?eXFUTFZTdXJ2R1V6aCtkZ1NmT1h0Y0lPdTUxZjhCOXdybWQ1REtjUkNZenBk?= =?utf-8?B?TXJ6RTVFK3pqRHkvcUVnS2l0Z2NkcHFUNWo2ZFJnd2wwaEFMQWVLQThnWHEz?= =?utf-8?B?OHNBRjVja25HYUpwYzFsTXp0bXBPMXZEUngyOW5UaDVRVmNIQUt0L2tIamhR?= =?utf-8?B?TUZaTVMyZ0F0QWNBZmJSV0ZGVk9vR0Z1UVdOYkRuS2cwRHNXNjZpNzdUb1Q5?= =?utf-8?B?N0x3TFFHOURXTmw0MFFERGdQbXJFTzRaU0NKSnk2ck9lMzd1VVdibzlQbGlC?= =?utf-8?B?R204elFtb3hMRlFQT2g1Wk1ITkthNHhuNm1QemR2WWh0NG94ZDRIS29SdGNa?= =?utf-8?B?blcxUWdTYUV0M0luRGJ1aTdSTnBrVmNyeUZiZWlyWVJFK1REV1VGR21GbUgy?= =?utf-8?B?Y25sM3pEaHlGbklsQTZDbW1TVTViWmYzcm5SV24vMThNSFJFK0JqR01vSDJI?= =?utf-8?B?TldjKzBQR09BLyszZEQ2eWwvcjl0TzdCakEwYXNpOVdpa3o0T3BMSDV0VlVK?= =?utf-8?B?Q3JpMGFXaWJPcXVlMU1KNmxPajZESkdMc2h0TzRNWXVOSGhPMmZBaXFTL1RQ?= =?utf-8?B?dDA5aEN1dEpCdnRqT2VNOEQ4UHRaNlJYMEVINnF4dVVhem1lelpscnQ1RFZ1?= =?utf-8?B?QVVISGx4NmdFL2FGNzRPRE96aUtXVW1GWFg1ZnFoVTFKdVRNRlQxQUtPS3px?= =?utf-8?B?V0JUVVZuTUdESEhlMXJ3YitSN2piaEtjUGY1enBUZys2ME5ud083MW16VnZ4?= =?utf-8?B?THVlQVlVZ0s1U0Zob1J1WkFiVXprR0xLSE9MY3RxOE5VWlZZWTBoeWkrTXJ5?= =?utf-8?B?YnZLdVVzeXlETGtoaEhzYXZtZ1hMZEFJbjFkckQzZ21SeGJyVjNxb1daVElk?= =?utf-8?B?ajQyU3A0K2t1N3FtTlpSUW9sVjJub2JPOWtDSmhsU2FJM0pOQUc2OFVReUY0?= =?utf-8?B?TVlZRkJNZ1BxUlNiNHlpcmRNcmdHU1NMMXZhZDRrdXFReERrWUxRQlpGRHd0?= =?utf-8?B?bGRCQTgyZHcxMzF4dUNlYU1jbFd2S0tnc205Y2FheHA2NlJFMjFuZDdxQjNH?= =?utf-8?B?ZDhRSisxQ2FBN3hLWDg5YU1kU1lMVWI3TFhROXJFYktxOEdKU09XUXdZdVM2?= =?utf-8?B?d0wxRURyZktjVkdYdWFaL0l1bUJMSFNHallXSHVtOUJTSkpyU0Z4VThyMTRG?= =?utf-8?B?N3FEbUJUM0hYM2JSS1pLMGFpWkZwd1VhN09uTjFWd0dieGc0Kzh6ZGt0TDdS?= =?utf-8?B?ZXl4ZGQzZEc4QWZwZVdEK2YwemFyOVJtWlJTM25KMnNxeVgwVmlBMHh6anF5?= =?utf-8?B?RWVpUitscWFVYjhueUdNb2JVUWNFcXZscVdXRGRaSUhCekZ3bFRGMGJJSEdO?= =?utf-8?B?K3UyOUhCbXRpeEFHKzZTeU9QRmZhQlpJMTVjWXJwVnRUWnlIOG9WeFNkYVZM?= =?utf-8?B?YmpmZHoyNFpWdUdJNlNWSktPSkphTFhydXNOMWhVcUtmdERObEpJWGRkQnd5?= =?utf-8?B?bW1ScXVWRnpGdXpiZ2hHeTFQQVY3b1puNWhlb3RsVE9RaW1tQTIrbmlvZXFD?= =?utf-8?B?YThXT05rejUwK3NWejBTT2VDWlZjakRLaUVrOWc2eERUNXFHVVltd0tBclMv?= =?utf-8?B?OG5BNUhzTEVjRHNrRGpyUkFRdGJITi82U3ZWeHV3RUU1Y3FHdFV1Tm5TRi9a?= =?utf-8?B?ODV4ODgwSENMbGhqbkZHYTZkY1NMSUJUU3QyeGQrT1ppenJFV0d2aEppYkM5?= =?utf-8?B?cWpoay9KYlpzMlR0d2kvWDB5QWhaajF6M3Z2KzNTRzFoSm94RW41SWI5b2JG?= =?utf-8?B?K1A0c05VcGxvcUcrTWR0VkNmbFZRbVowQzB2aFU3UnFCU2ZuamlHbjlkTDVZ?= =?utf-8?B?dGMvNE9Uam90U0hzdm9KdkxRV2FzaU03cVJSR1hpcEpDZ05ubkh0dz09?= X-OriginatorOrg: garyguo.net X-MS-Exchange-CrossTenant-Network-Message-Id: 48b3b6b3-18f4-4be2-5aa0-08dee748bec9 X-MS-Exchange-CrossTenant-AuthSource: LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jul 2026 16:54:35.8411 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bbc898ad-b10f-4e10-8552-d9377b823d45 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: l1TsTYq3T1O8xAlixo6iewnCqsRThCaVYdcgyxy3eC7j7L4xh5bLrgDqpdH0AnyBZ1X2VH9bDmNTBqhzVG1RpQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LO8P265MB7878 Previously `register!` defined registers can be used on any untyped I/O regions. With all users specifying their desired register type now, propagate the specified type and restrict I/O access only when type matches. Signed-off-by: Gary Guo --- rust/kernel/io/register.rs | 111 ++++++++++++++++++-----------------------= ---- 1 file changed, 45 insertions(+), 66 deletions(-) diff --git a/rust/kernel/io/register.rs b/rust/kernel/io/register.rs index b0fcfce36c9c..df47c28ba4f4 100644 --- a/rust/kernel/io/register.rs +++ b/rust/kernel/io/register.rs @@ -121,10 +121,11 @@ io::IoLoc, // }; =20 -use super::Region; - /// Trait implemented by all registers. pub trait Register: Sized { + /// Base type for this register. + type Base: ?Sized; + /// Backing primitive type of the register. type Storage: Into + From; =20 @@ -139,9 +140,9 @@ pub trait FixedRegister: Register {} =20 /// Allows `()` to be used as the `location` parameter of [`Io::write`](su= per::Io::write) when /// passing a [`FixedRegister`] value. -impl IoLoc, T> for () +impl IoLoc for () where - T: FixedRegister, + T: FixedRegister, { type IoType =3D T::Storage; =20 @@ -153,9 +154,9 @@ fn offset(self) -> usize { =20 /// A [`FixedRegister`] carries its location in its type. Thus `FixedRegis= ter` values can be used /// as an [`IoLoc`]. -impl IoLoc, T> for T +impl IoLoc for T where - T: FixedRegister, + T: FixedRegister, { type IoType =3D T::Storage; =20 @@ -178,9 +179,9 @@ pub const fn new() -> Self { } } =20 -impl IoLoc, T> for FixedRegisterLoc +impl IoLoc for FixedRegisterLoc where - T: FixedRegister, + T: FixedRegister, { type IoType =3D T::Storage; =20 @@ -249,9 +250,9 @@ const fn offset(self) -> usize { } } =20 -impl IoLoc, T> for RelativeRegisterL= oc +impl IoLoc for RelativeRegisterLoc<= T, B> where - T: RelativeRegister, + T: RelativeRegister, B: RegisterBase + ?Sized, { type IoType =3D T::Storage; @@ -293,9 +294,9 @@ pub fn try_new(idx: usize) -> Option { } } =20 -impl IoLoc, T> for RegisterArrayLoc +impl IoLoc for RegisterArrayLoc where - T: RegisterArray, + T: RegisterArray, { type IoType =3D T::Storage; =20 @@ -380,9 +381,9 @@ pub fn try_at(self, idx: usize) -> Option> { } } =20 -impl IoLoc, T> for RelativeRegisterA= rrayLoc +impl IoLoc for RelativeRegisterArra= yLoc where - T: RelativeRegisterArray, + T: RelativeRegisterArray, B: RegisterBase + ?Sized, { type IoType =3D T::Storage; @@ -408,9 +409,9 @@ pub trait LocatedRegister { fn into_io_op(self) -> (Self::Location, Self::Value); } =20 -impl LocatedRegister> for T +impl LocatedRegister for T where - T: FixedRegister, + T: FixedRegister, { type Location =3D FixedRegisterLoc; type Value =3D T; @@ -850,37 +851,10 @@ macro_rules! register { $(=3D> $alias:ident $(+ $alias_offset:ident)? $([$alias_id= x:expr])? )? { $($fields:tt)* } )* - ) =3D> { - const _: () =3D { - #[allow(unused)] - fn test_base(_: &$reg_base) {} - }; - - $( - $crate::register!( - @reg $(#[$attr])* $vis $name ($storage) $([$size $(, stride = =3D $stride)?])? - $(@ $($base +)? $offset)? - $(=3D> $alias $(+ $alias_offset)? $([$alias_idx])? )? - { $($fields)* } - ); - )* - }; - - // Entry point for the macro, allowing multiple registers to be define= d in one call. - // It matches all possible register declaration patterns to dispatch t= hem to corresponding - // `@reg` rule that defines a single register. - ( - $( - $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) - $([ $size:expr $(, stride =3D $stride:expr)? ])? - $(@ $($base:ident +)? $offset:literal)? - $(=3D> $alias:ident $(+ $alias_offset:ident)? $([$alias_id= x:expr])? )? - { $($fields:tt)* } - )* ) =3D> { $( $crate::register!( - @reg $(#[$attr])* $vis $name ($storage) $([$size $(, stride = =3D $stride)?])? + @reg [$reg_base] $(#[$attr])* $vis $name ($storage) $([$size $= (, stride =3D $stride)?])? $(@ $($base +)? $offset)? $(=3D> $alias $(+ $alias_offset)? $([$alias_idx])? )? { $($fields)* } @@ -892,22 +866,22 @@ fn test_base(_: &$reg_base) {} =20 // Creates a register at a fixed offset of the MMIO space. ( - @reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) @ $offse= t:literal + @reg [$reg_base:ty] $(#[$attr:meta])* $vis:vis $name:ident ($stora= ge:ty) @ $offset:literal { $($fields:tt)* } ) =3D> { $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storag= e) { $($fields)* }); - $crate::register!(@io_base $name($storage) @ $offset); + $crate::register!(@io_base [$reg_base] $name($storage) @ $offset); $crate::register!(@io_fixed $(#[$attr])* $vis $name($storage)); }; =20 // Creates an alias register of fixed offset register `alias` with its= own fields. ( - @reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) =3D> $al= ias:ident + @reg [$reg_base:ty] $(#[$attr:meta])* $vis:vis $name:ident ($stora= ge:ty) =3D> $alias:ident { $($fields:tt)* } ) =3D> { $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storag= e) { $($fields)* }); $crate::register!( - @io_base $name($storage) @ + @io_base [$reg_base] $name($storage) @ <$alias as $crate::io::register::Register>::OFFSET ); $crate::register!(@io_fixed $(#[$attr])* $vis $name($storage)); @@ -915,44 +889,47 @@ fn test_base(_: &$reg_base) {} =20 // Creates a register at a relative offset from a base address provide= r. ( - @reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) @ $base:= ident + $offset:literal + @reg [$reg_base:ty] + $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) @ $base:i= dent + $offset:literal { $($fields:tt)* } ) =3D> { $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storag= e) { $($fields)* }); - $crate::register!(@io_base $name($storage) @ $offset); + $crate::register!(@io_base [$reg_base] $name($storage) @ $offset); $crate::register!(@io_relative $vis $name($storage) @ $base); }; =20 // Creates an alias register of relative offset register `alias` with = its own fields. ( - @reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) =3D> $ba= se:ident + $alias:ident + @reg [$reg_base:ty] + $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) =3D> $bas= e:ident + $alias:ident { $($fields:tt)* } ) =3D> { $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storag= e) { $($fields)* }); - $crate::register!( - @io_base $name($storage) @ <$alias as $crate::io::register::Re= gister>::OFFSET + $crate::register!(@io_base [$reg_base] + $name($storage) @ <$alias as $crate::io::register::Register>::= OFFSET ); $crate::register!(@io_relative $vis $name($storage) @ $base); }; =20 // Creates an array of registers at a fixed offset of the MMIO space. ( - @reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) + @reg [$reg_base:ty] $(#[$attr:meta])* $vis:vis $name:ident ($stora= ge:ty) [ $size:expr, stride =3D $stride:expr ] @ $offset:literal { $(= $fields:tt)* } ) =3D> { $crate::build_assert::static_assert!(::core::mem::size_of::<$stora= ge>() <=3D $stride); =20 $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storag= e) { $($fields)* }); - $crate::register!(@io_base $name($storage) @ $offset); + $crate::register!(@io_base [$reg_base] $name($storage) @ $offset); $crate::register!(@io_array $vis $name($storage) [ $size, stride = =3D $stride ]); }; =20 // Shortcut for contiguous array of registers (stride =3D=3D size of e= lement). ( - @reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) [ $size:= expr ] @ $offset:literal + @reg [$reg_base:ty] + $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) [ $size:e= xpr ] @ $offset:literal { $($fields:tt)* } ) =3D> { - $crate::register!( + $crate::register!(@reg [$reg_base] $(#[$attr])* $vis $name($storage) [ $size, stride =3D ::core::= mem::size_of::<$storage>() ] @ $offset { $($fields)* } ); @@ -960,7 +937,8 @@ fn test_base(_: &$reg_base) {} =20 // Creates an alias of register `idx` of array of registers `alias` wi= th its own fields. ( - @reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) =3D> $al= ias:ident [ $idx:expr ] + @reg [$reg_base:ty] + $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) =3D> $ali= as:ident [ $idx:expr ] { $($fields:tt)* } ) =3D> { $crate::build_assert::static_assert!( @@ -969,7 +947,7 @@ fn test_base(_: &$reg_base) {} =20 $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storag= e) { $($fields)* }); $crate::register!( - @io_base $name($storage) @ + @io_base [$reg_base] $name($storage) @ <$alias as $crate::io::register::Register>::OFFSET + $idx * <$alias as $crate::io::register::RegisterArray>::= STRIDE ); @@ -978,14 +956,14 @@ fn test_base(_: &$reg_base) {} =20 // Creates an array of registers at a relative offset from a base addr= ess provider. ( - @reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) + @reg [$reg_base:ty] $(#[$attr:meta])* $vis:vis $name:ident ($stora= ge:ty) [ $size:expr, stride =3D $stride:expr ] @ $base:ident + $offset:literal { $($fields:tt)* } ) =3D> { $crate::build_assert::static_assert!(::core::mem::size_of::<$stora= ge>() <=3D $stride); =20 $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storag= e) { $($fields)* }); - $crate::register!(@io_base $name($storage) @ $offset); + $crate::register!(@io_base [$reg_base] $name($storage) @ $offset); $crate::register!( @io_relative_array $vis $name($storage) [ $size, stride =3D $s= tride ] @ $base + $offset ); @@ -993,10 +971,10 @@ fn test_base(_: &$reg_base) {} =20 // Shortcut for contiguous array of relative registers (stride =3D=3D = size of element). ( - @reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) [ $size:= expr ] + @reg [$reg_base:ty] $(#[$attr:meta])* $vis:vis $name:ident ($stora= ge:ty) [ $size:expr ] @ $base:ident + $offset:literal { $($fields:tt)* } ) =3D> { - $crate::register!( + $crate::register!(@reg [$reg_base] $(#[$attr])* $vis $name($storage) [ $size, stride =3D ::core::= mem::size_of::<$storage>() ] @ $base + $offset { $($fields)* } ); @@ -1005,7 +983,7 @@ fn test_base(_: &$reg_base) {} // Creates an alias of register `idx` of relative array of registers `= alias` with its own // fields. ( - @reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) + @reg [$reg_base:ty] $(#[$attr:meta])* $vis:vis $name:ident ($stora= ge:ty) =3D> $base:ident + $alias:ident [ $idx:expr ] { $($fields:tt)*= } ) =3D> { $crate::build_assert::static_assert!( @@ -1014,7 +992,7 @@ fn test_base(_: &$reg_base) {} =20 $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storag= e) { $($fields)* }); $crate::register!( - @io_base $name($storage) @ + @io_base [$reg_base] $name($storage) @ <$alias as $crate::io::register::Register>::OFFSET + $idx * <$alias as $crate::io::register::RegisterArray>::ST= RIDE ); @@ -1035,8 +1013,9 @@ fn test_base(_: &$reg_base) {} }; =20 // Implementations shared by all registers types. - (@io_base $name:ident($storage:ty) @ $offset:expr) =3D> { + (@io_base [$reg_base:ty] $name:ident($storage:ty) @ $offset:expr) =3D>= { impl $crate::io::register::Register for $name { + type Base =3D $reg_base; type Storage =3D $storage; =20 const OFFSET: usize =3D $offset; --=20 2.54.0 From nobody Sat Jul 25 00:16:38 2026 Received: from LO3P265CU004.outbound.protection.outlook.com (mail-uksouthazon11020086.outbound.protection.outlook.com [52.101.196.86]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8D5543932E4; Tue, 21 Jul 2026 16:54:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.196.86 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652888; cv=fail; b=q36/gx3fsDtO/lw15DwSSZs39jD5Iwyl3sCHBpSG1Km4uFCpYRdH9MRV4opYMb9VM7TiIWcBavLB69g4nTs0x36KghyBI9qon0Jag3irdOY7Z7uBA32qOMqFCaLoVCqQM93TH7EheY7LZVIWuowjXs2Yy9oRkK1U+O11eMD++R8= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652888; c=relaxed/simple; bh=KJDfs+244AAMtetB/l4yAX6DwbO7wS8IunR7KoFI2os=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=B+8v8JeqVRGB3sdlxhuKTQs7P2Hn44WwrKl/55Ipj4wivrylp1xzO3osNm6/so7AIDJPgJeoLhKEiNRd6fHo00nMHm8hsfpIa2ZXLzehgthgwlfSTmzc942emDxhB612XFT7JkNJrcvrV9GcTOOW41XjNfPoHe/XkyDQBPo9C3Q= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net; spf=pass smtp.mailfrom=garyguo.net; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b=sdQs724J; arc=fail smtp.client-ip=52.101.196.86 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=garyguo.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b="sdQs724J" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=x5PPDqxf4IOb5UU1MvzOGQbyDP0KrnlwOlO5GRhtq/AEZO5i0PrhsfHNOH86w88jXJiBd4pxQxZXGSSNjgI0VqsKAC4UEeX8PYPFkjPABJS8M8vgLt/38TWqfoKXuR8nq3FZwdtZqs5W0rZJ94715HGy9d4aQIGyOfqILNkmZibp1XZm1crkSYoveRqAq9W3U5GgtDJNFbLSLRPjCzPraeoNEH5pS5vW4gKD4WiqO+c3YxEvjeCfcTyaksvUfoFv8To1nvvzrl6qhxNqDyiXh33KrvUqarKlLdkz//pJmua3ViuYgDMVJrKu3ZbQDR1IECtvuE8fqKVGoogFrXsA6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=RoX/PgW3xQetTzFxJEl0t/PJxwXjQCnEefgN0cRnG80=; b=ZxDBX+HYDkEi23cwsnUDplH4eZTzqm6YZ3Id/9kdQcfBuz1HnyycJVgiL0sk+v1BU1g8lcagoz/p0k2GxUnoi5wkw+oBkIJXkjlY2Pr/cXkkpX5XrDgx4hwaGhRdOw7Wvgfzw97xBga5DQWB6XfA3BkZasIfU159U6vawbQowSHPwGm4qz+ZaAw5A49yDTSU8Y7aZELMoMOzjjWF9JmubeeaBNBUXC9ipSnIAMasGrbV84mK22kumHm1u9AVU9Sa9VrkMA7dg1WpwPrLWhibeoY+nNkG6hC0T83jYHBf0avdDb0UkstfGZWadxFQEuXtoQ3AjQSY7ToQqJGt9MiJbw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=garyguo.net; dmarc=pass action=none header.from=garyguo.net; dkim=pass header.d=garyguo.net; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=garyguo.net; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=RoX/PgW3xQetTzFxJEl0t/PJxwXjQCnEefgN0cRnG80=; b=sdQs724JSL47V439Yw96/Hm/7dDr5OuMPRILy82Rt53mW226jRp9G/N2QYK1TZgkjCkvLO3PlU2pyEZ72Fg9MIGKX0WUBo9GT7v8cGm4eNQ7e0m6a68pn9zftHeLxZirrP9e8VwAk76+8pPByk7MBTXUE2MTr+A5f3wVMDeLj1c= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=garyguo.net; Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) by LO8P265MB7878.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:3ae::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Tue, 21 Jul 2026 16:54:36 +0000 Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986]) by LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986%4]) with mapi id 15.21.0223.017; Tue, 21 Jul 2026 16:54:36 +0000 From: Gary Guo Date: Tue, 21 Jul 2026 17:54:30 +0100 Subject: [PATCH 06/10] rust: io: add static `cast()` method for views Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-typed_register-v1-6-452d72b60262@garyguo.net> References: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> In-Reply-To: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> To: Danilo Krummrich , Alice Ryhl , Daniel Almeida , Miguel Ojeda , Boqun Feng , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , David Airlie , Simona Vetter , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= Cc: driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, linux-pci@vger.kernel.org, Gary Guo X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784652872; l=1983; i=gary@garyguo.net; s=20221204; h=from:subject:message-id; bh=KJDfs+244AAMtetB/l4yAX6DwbO7wS8IunR7KoFI2os=; b=Vkh6H5OA032gZOXm5xCuKU9T1Ca3JyZKpXO4AlnPSSpObxfzSzg/uFtBpEijEVXCIhsS1XAzd pXcBNj+XeQDDPw5IEmzu/Zj/meQaYxZJ2dLbpdz5sNLiqbRZPnCXpE9 X-Developer-Key: i=gary@garyguo.net; a=ed25519; pk=vB3uIX95SM4eVrIqo1DWNWKDKD2xzB+yLLLr0yOPYMo= X-ClientProxiedBy: LO4P123CA0143.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:193::22) To LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LOVP265MB8871:EE_|LO8P265MB7878:EE_ X-MS-Office365-Filtering-Correlation-Id: c1693ba9-f43c-4955-4c6f-08dee748bf1d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|7416014|10070799003|1800799024|366016|56012099006|10067099003|6133799003|22082099003|18002099003|921020; X-Microsoft-Antispam-Message-Info: bGpciIE77r4KDe/5fhD9QhTQWhi+FGQNm+VlSu0Gq9SpWknB0YUiYKSZMx2AL56Euj6h6SX81p/kS3/yFNK7wVbTks+PxfNLGpf1l0LfVWTnfZh7eTCobCOHq7PzBl2Sdv5fNVcVniUNQoavAeVEhS2PikGnaQyCtfoW+hyuLYZFNdObYS3LgnX6ndDtXks/NuRxqPf6tJN8FY9jsN44lCOIfhkb6eFc/df0nECqQ52o0Y4EnU4zd6CCN4cMlXXdZP+6eZYBZX8KmqxkgIw2XacO3LjRXr0Fo9It25trHv4uFOLZPs/vdpBLxccWJFnwlCOk8zD4bVXUVvwznYMeHJ7k01Na74HFVlpxKz2ltsDOzVLuztVrZUDe5epUHKogV9rAhvr5ny2kvjtjDIsHKQG3uhCWlPAzcNbAk6uuf4EmAfzZRN9c/IPnSpyqZAXa8NldlkNYqGu2RNyaVaw9n1SmVKHqhhWOx0bRELJBtR0vmlkQI/rJDJWyZRZ0OV/rIsOzHkPBFeAmNNIyxPfnSCb2farSmR3i+MzpsMDwXX+OGEUXEMH0JVbMgRKOxVGftfiH7zlfNBu/OuSYlN6L1RXqsHWV6jZttB6KD6rmXT0hdoCqLkSL3VRMHl/h2pypmcyMtFfz9BwzHIyQZ7IX6ZkPPFUZGRpD0pEe0MGuBDdY6qLQP8NWlff7Y+w++hC4w1o4W0OSCy7/jICXbDMzlA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(376014)(7416014)(10070799003)(1800799024)(366016)(56012099006)(10067099003)(6133799003)(22082099003)(18002099003)(921020);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?V0VVRXdvTW40emZiZ3QzS0ZwaGp4SGVWbXluaXVzaURTNGxzZmdkL0tObWQ1?= =?utf-8?B?T2lGZFh3MEdzMW9uZWRZOHZETjZuRzJaSnNJazdKVzB5dy9VeXlnbTA0YWNh?= =?utf-8?B?VEZ0K0JlUkR2MXE5NUZwU2RtRmI3dnhHOFJMdWVxdVR3YTkwSXBOZTZQTUhE?= =?utf-8?B?aEMxcmsydnJzcHhLanVvL0FVblEyNHFseTVZVnhnV21zUW83RnF6NDBFRm51?= =?utf-8?B?am1RYUczaFlBVUpYOWZVblNXcVhNWTRudVA4bkIxVStYZHcwM1ByUFFGWHF2?= =?utf-8?B?cFBOZjIxZ0gzNC9SVGUxOFk1WWMxSkNTSDQ1d0JHT3kyZVc4ZE1UQ1RZZ0tj?= =?utf-8?B?K04yMWR3bXJNQitpdVF0N3hoMDRUdnErNThOREYyQVdHcnZzTmlNZEtET1c4?= =?utf-8?B?YmNhQkw0T3FVR2VSUWVrT3VlWk11T1dRSnVObUhmV29XSktkcFE1anZVdFZh?= =?utf-8?B?ajJ5a0FxSmgyTDdySDVoVXZtQ0krelZaVldQaUhpNGw5MTdROE1JQSt4MjZw?= =?utf-8?B?NVBaSDBhVE96dFdvNFFEQnV1cU1DOWFINVZVZkpIMFJhVE02NVJYeGM2cnpY?= =?utf-8?B?bFJtblY3Zys0YmxoUmptb1RpNTU4QUtzVXdJZUtOTjBUV1MwOTFicG85ei9U?= =?utf-8?B?TkVtVk0vM1dKMVdhWkIzWkFKOS9ZYVJQZ1VXTnZzYzdvS0pvT2VVajR0aG9v?= =?utf-8?B?RnRieTN5RnRhSjBPMCsvV1oxckw5VHFoTzVCcUFUME51YWl1RlFMYUhaOXlV?= =?utf-8?B?dUgwNzdVUmxFR1VMeFFRUVI1V1BZVTNEOHRUaUgxUGVGaFY5UHEwRmIxSEt3?= =?utf-8?B?aTFuTUk3dThxaXFtbG5pOFBZRGxWSjVDQ2Z6Q3RzQ0VrRXFkOUtoT005RjVB?= =?utf-8?B?V1YvM1BZWVhpanh2RURtMCsxUTJ0V2tMWTI3b2FNZ0dlYjFsN2xlQjBiYnEy?= =?utf-8?B?Vm5mR1ZBUEllYVVUV2g1SkdxdzhIcmVqbTNDbi9SaHBIRldXay84M3VKMWlL?= =?utf-8?B?bTJRcU9zWDF2NktuUmRUZFlCQk9LNFpzOExzd3h0ZTZnTTN5Z2tSRk4zcU5u?= =?utf-8?B?R3IzemhQWXR6S3ROcjAzSkZXM0kzcEdPTGVsQm5hdDhKUGVXcTVJb0pRNldn?= =?utf-8?B?c0JwTXNyL0hFQUwyVlBaRFJHRXlvek1zVUE3eFZKNE5NUTdZOFFlbVNmTXFB?= =?utf-8?B?NzlEc0I0SytKcEJlSTl3S0hOajF1MjR5d3NHWFVQRFo5bTVvYW5rbGpZMEtS?= =?utf-8?B?eEJiMU9XTUZ4OFBVc0pXSGkrOU1DUk53MGRxT285bDNUV0Q2YVdCQ1dPNUNv?= =?utf-8?B?TmV2OW5GUGdaa3UvcmVTa2dReC9veDVEWFJuMVlwQ2ZZWVBMR2w3dFdkNXFl?= =?utf-8?B?L1VQN1FXd0E1aXZra1dzbHA2OTZXWkt6aDNsZVZOM1NWeEhDNDZuTG1MdEFm?= =?utf-8?B?RExnWnVLM3JaYVkrZGFMVlVMSDBzRHZ3V3JGRm5KZUxXdjMza0lmNzdzbitj?= =?utf-8?B?L2tkOTdYWSt6Mk1qWmhmWGtLaUp6TG5pQkxoQVlFdUxqa2FZUTU4L2RaQlRO?= =?utf-8?B?MDN3OEVGSWRQZlFRUEVuQlROdDUyOXFadWdmcnlNMkoyVU0rN3J2M1lWTFFx?= =?utf-8?B?ZGMvRXp6ZkJaMlVFUGZuRjdsWUpLMzYwQ3lxakhTd3VoYWp0N3l3NkpvSjlN?= =?utf-8?B?V1JudGtieXJnZjVSV09sWktubTJqMUNqamg2ZFFQRTJYdkt0N3BJQjVTK2NF?= =?utf-8?B?dFBsTncxRTlUdTNGc2taUXRaTjY2NTVya0tLbmtueklYMW8vTzhLWFlyb0dB?= =?utf-8?B?K3phczh4YmJXQmFQVmlzYVVWbWIzdktJMy9KTlRoWllkSnF4SG9KbmtVeEdH?= =?utf-8?B?eExyaFJkcUFOSjkxWUFlOVJuWTc1b2ZaM1ljR0VCUk5lNHBGVTJHdW5oa0gz?= =?utf-8?B?czNPcGJmR1NMRTFIcks4ZC95cUU2WjZidXZ1YWU4d3dpano0dWp5VjRTSzdk?= =?utf-8?B?MFFzdld5MHJNYnRDRHM3cUpNZnJUTVpuMVd6TEpRV3VOTFZaQ1hyemRVUUJU?= =?utf-8?B?TktUS3pmZUprRllLcDArODk0MnF4WEl3eThuZy9VNitWSFVLbndWeTJTeFRL?= =?utf-8?B?ZmV3K0N5ME0rYnA4NzUzNE5wNFlRb0ViTmwvVGROYTg4bWpKbU5iUnFXTXZT?= =?utf-8?B?TTVQaFVXRExLS2VpVUJmcS9WcVA1TUIxOWtWemorZVFUYnlmcG5UZVdWZlJZ?= =?utf-8?B?RExIanQxWmlGR3l6d1ZYSTVieDNuNjM5SUU0RzRqcmozWkQ4UDkrWE5kd3Zs?= =?utf-8?B?dHJOQXQyRWxpSjdDbThVUmltTy9vd25KSlpRTnJzV3I0ZGZaUVVvZz09?= X-OriginatorOrg: garyguo.net X-MS-Exchange-CrossTenant-Network-Message-Id: c1693ba9-f43c-4955-4c6f-08dee748bf1d X-MS-Exchange-CrossTenant-AuthSource: LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jul 2026 16:54:36.3751 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bbc898ad-b10f-4e10-8552-d9377b823d45 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: TjAOhSu2qXZWEbN5yTMKtkAYY+sdsDTJZ9jY2t5pYkQREQA80QKV20POE8gQ9PyUFc50gWI4tkytEa7iOZkOnQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LO8P265MB7878 Add a compile-time checked variant of `try_cast()` using the minimum size and alignment information. Signed-off-by: Gary Guo --- rust/kernel/io.rs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs index c5f07c38e59e..0f8b166a6d3b 100644 --- a/rust/kernel/io.rs +++ b/rust/kernel/io.rs @@ -436,6 +436,45 @@ fn is_empty(self) -> bool self.len() =3D=3D 0 } =20 + /// Convert into a different typed I/O view. + /// + /// The target type must be known (statically) to be of the same or sm= aller size to current + /// type, and the current view is properly aligned for the target type. + /// + /// # Examples + /// + /// ```no_run + /// use kernel::io::{ + /// io_project, + /// Mmio, + /// Io, + /// Region, + /// }; + /// #[derive(FromBytes, IntoBytes)] + /// #[repr(C)] + /// struct MyStruct { field: u32, } + /// + /// # fn test(mmio: &Mmio<'_, Region<0x1000>>) { + /// // let mmio: Mmio<'_, Region>; + /// let whole: Mmio<'_, MyStruct> =3D mmio.cast(); + /// # } + /// ``` + #[inline] + fn cast(self) -> ::View<'a, U> + where + Self::Target: FromBytes + IntoBytes, + U: FromBytes + IntoBytes, + { + let view =3D self.as_view(); + let ptr =3D Self::Backend::as_ptr(view); + + const_assert!(size_of::() <=3D Self::Target::MIN_SIZE); + const_assert!(align_of::() <=3D Self::Target::MIN_ALIGN.as_usiz= e()); + + // SAFETY: We have checked bounds and alignment, so this is a vali= d projection. + unsafe { Self::Backend::project_view(view, ptr.cast()) } + } + /// Try to convert into a different typed I/O view. /// /// A runtime check is performed to ensure that the target type is of = same or smaller size to --=20 2.54.0 From nobody Sat Jul 25 00:16:38 2026 Received: from LO3P265CU004.outbound.protection.outlook.com (mail-uksouthazon11020086.outbound.protection.outlook.com [52.101.196.86]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79D133998AF; Tue, 21 Jul 2026 16:54:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.196.86 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652890; cv=fail; b=Robr8M0dyR73q7lgUPjFmjCQnraUFBrnU3YHF4URhyjGjyL3Z/m/R8sP2TCnYAGgjivBiv1rKyDFG+a8vYFhxgGbEBVQZtzPz+9RcY07ZcbYmTmh3I/Vhfdp3S8KcZ9fnsmb2XsaiLYsbR4zEk8s5WPnYkHYVQCqrxNe7xIt4VA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652890; c=relaxed/simple; bh=UuUtulP5TTsCiBoLOzge4yJEZnhJxQB6CbEM3NnyO3k=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=JyDa3ytAW50jJkbPaZEaQx0KbQi5PjXJNRL6sN3l4H+OmiHbDVO1oQyOcmQB95JmBkB81hH2qw7IB/KxKXXIpPhEnKhQTIAL+aautRZ6L6NPEoyBermVDv6DArgJ45y3+VIlZnPzGy3QzPPeTeMOCiCAxANhbhwuDcI2BlKSLNQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net; spf=pass smtp.mailfrom=garyguo.net; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b=K5GYwA5P; arc=fail smtp.client-ip=52.101.196.86 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=garyguo.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b="K5GYwA5P" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ekqYpn8vkki3pXkQvKkiPAyUO2KE9S3hKMjYT5Jsy+5+k4qvSJOZ/Q4fA+dv8IeB7HkO63j0/S4yy8lbxgT61/8zC6N4CcsB6/ncRGGb5WotAZw2n0XidGZdcpITB76Xgz3X7UlGtCfMrYE0ee0oF6Ftc9bErzefqn+8JJ7wDrjWEhXLPHggGUMZDuUcLFUFIEuArYBoHzLcgiTUUf/Oiy5K7ySm8GFv+YocqhNoQ7qYxcCETTBLRdSVJZAZwagc2dXn4TAxoHD/XXSOONr3gVrMCe7lsZMjfvCjkgJzNgmHaBqCDT/Xew6pXDrK5pv3mA90D/E8usFlfR5WGz3Jjw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=X3Q6cgY4/fY7xuRsxeLLgbo2v/hJYuFRyehKXpZR8Vk=; b=xkCsD9T6dgXlp84rHNlvRcNWnJk+ZlN2C1M0wb5XIC8kH+7YH8xqgvGfo6r+/3ExmnRpWQFvEMSldeWnAg+zjmYPZeHAMlhICJvM3qpzRFwbqjxBCoxYzevDyGzZIRs6NG/f65b13adEFlZgf97fyYmSy2dPcNPRH2fYSsgopSHMapoPyEV8oEScpTAi5oKsfBnEPcULIXhBc7X3f1bV9eXjzwGgxCPLomQEReKIWm3tolvTWIieW8E/kOzKj0FweCxSu2vaRd0MHD1gzJEcZ6AjlBcFWj4Ah5twIwMSOv88edM84XSQkIetO3xXOJovG/4+cw58MkgZ7BBkvuPFBQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=garyguo.net; dmarc=pass action=none header.from=garyguo.net; dkim=pass header.d=garyguo.net; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=garyguo.net; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=X3Q6cgY4/fY7xuRsxeLLgbo2v/hJYuFRyehKXpZR8Vk=; b=K5GYwA5PXCxJ6yGnBjI3I0iQw7lZFl1Llf96aMqp1/7fwQgsb6QAzZAopL2gi5VTj+ORaCxLLMYTDy77Rs4XiRkVD358ssd3hzVwazM6mvKVGhM0gYMYRqVk7TvgJhpDF/HZJpfDkOy+yfQK/wlBTIH9/LE5IrWZq9uC4in/rko= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=garyguo.net; Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) by LO8P265MB7878.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:3ae::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Tue, 21 Jul 2026 16:54:36 +0000 Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986]) by LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986%4]) with mapi id 15.21.0223.017; Tue, 21 Jul 2026 16:54:36 +0000 From: Gary Guo Date: Tue, 21 Jul 2026 17:54:31 +0100 Subject: [PATCH 07/10] rust: io: add subregion method with compile-time check Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-typed_register-v1-7-452d72b60262@garyguo.net> References: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> In-Reply-To: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> To: Danilo Krummrich , Alice Ryhl , Daniel Almeida , Miguel Ojeda , Boqun Feng , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , David Airlie , Simona Vetter , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= Cc: driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, linux-pci@vger.kernel.org, Gary Guo X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784652872; l=1603; i=gary@garyguo.net; s=20221204; h=from:subject:message-id; bh=UuUtulP5TTsCiBoLOzge4yJEZnhJxQB6CbEM3NnyO3k=; b=yg0dCdKIQhekGtnJvoKnddBHFJmyJscAKVBw6HTvuwiMpITAtcWA9eddeR1ByCQcgcjjxPVGG eUZ+Z5C08FgBYknqTU/m76xi0ltzscB8/XYMjN9EK7C5qG/bdEVHdpA X-Developer-Key: i=gary@garyguo.net; a=ed25519; pk=vB3uIX95SM4eVrIqo1DWNWKDKD2xzB+yLLLr0yOPYMo= X-ClientProxiedBy: LO4P123CA0143.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:193::22) To LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LOVP265MB8871:EE_|LO8P265MB7878:EE_ X-MS-Office365-Filtering-Correlation-Id: 20c14eb5-955c-4b80-36ba-08dee748bf6b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|7416014|10070799003|1800799024|366016|56012099006|10067099003|6133799003|22082099003|18002099003|921020; X-Microsoft-Antispam-Message-Info: CgeRoiluuHCihLcSErSHzoV7Zcti384C/6dmzgPqGHHWGDd1A+BxhX967OJTlNY+Dx8dy4nsH76pK8noiI/B38FvTxEW3iPZIqjSL1SjkiYdM4zCF3Dcd82FYuoSg55ktA6git3WmkyiBF3HIaJclNrk38zi0rWmdlNfF0ubU0g441EyGRuGfCF1DsV75wssCcyJeeyzuRtHLPfIFpNt3dejFGUCmoGVkBUcK8nDgYFjChQc8E26fDiTSu0bFxmVEWMfPrrgSkCxwNtCrynQsVeINH91B3+yPzt1A96mvAC6qb0mPOOcEkKPQPg8oA2vTiyIKHT3JA5VprJqb4/+NLYRQjMRv+Z3AyRq7yKt1dW6BpaGQrcxZS41YEEBALfWHO1mNeVA1BOHwqELv7VjJYXqrpYDfUXSv3OFeLHBhVIMz4fbJFfpa120qJTIBWOQwcwPN8J82TQ1sqoIHDGr5tSP8zHuia2yTe0fWQ1JZ1ftw53zOT+TSxNQmx9QkGse1OWejKdkq2tFp/+Sl2kqTZKYswBkd+JXa3ZqrSZvKXgCXWpSfDyzT3xX2Cw371zjITS1ryyIsJUJ3hORZjgAm4zz2IlMmeYOD9T8lefzdE4iO8aI7wanvf7gp1sRsWvHSErr5O4c4HE7o7YeCy9A9VB5QC5ACvP9OxVCCOR/Y01MYI+2f5aIX7bxpUVGlJX0ij7dqyLu+3z6AwBT/jkfsA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(376014)(7416014)(10070799003)(1800799024)(366016)(56012099006)(10067099003)(6133799003)(22082099003)(18002099003)(921020);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?U1h3dXFzeDRrNVpEU2Z4T1F4N1Yxbk5aN2p0bmR2R3N3Ymx3ZWEvNzBDYUNZ?= =?utf-8?B?ZVF6R2NCSTJKVEUxaFVsbTI3MDZQeFNBcmluTUVwVHhKR2VyOGJ6cHdyeWVt?= =?utf-8?B?Umlnc09BanMwbVpRbDRDbmpnb1ZRNXFDOTJIS3VBaStMdElyQUdBSVQ0SXpy?= =?utf-8?B?SGoyNFlST2cwWFFNblF3VUliTXVvMVh4VTVPQ1N0dFRpcVJtS1dzTlA5dVRT?= =?utf-8?B?ZlU4cUpFbVgwcHFBOXVxYjZWVEF1bGIrcExqaWpubGRxN1VydmxPcW1wLzk2?= =?utf-8?B?dzNOK2g0cElTd2xUaDdLZnlqZWxMd2YvODBJVWVWUWZsdFNYUVpxdGtGMWpr?= =?utf-8?B?aThXUEJsQmpwUWpGOUE5QWRrN2ZkVDZIY0VCTVNYYkY2NFdlVDRBdms4ODEw?= =?utf-8?B?S3FjaUNFMk83Q0daL1BRajhzQ3F2NkEyUUt1YVpRMmM1M3dGemU0eXYwZ0xF?= =?utf-8?B?OTlzcDliZFNWTnhEenR2RWNoa2JBRGROY3Viek0zN1RpQmE2ZERUa3ZNRFk2?= =?utf-8?B?MHR4YkVtaFh5OUhoQ2tBeG5lTG9uckZFYkRXNmo0dVdzNWtVdXc1RmRVaXIw?= =?utf-8?B?UXNxTEFlL2dYc3FGK013KzN1aGNBQUlLZUlRQ2dLbERlK0c3NVBRSDlncnZu?= =?utf-8?B?Wlc1Mzh0U09NMWJJNGNRczZiQW51QjZucWZhekRwenhlaitjQnkxbDFXczdV?= =?utf-8?B?a3A0cWc3Tk9qUSs3c08wd3ZHZlE1MHU4T3piNTVBYStja2xlYnV0VFNJajUz?= =?utf-8?B?elJZOVZuNUVjYW9HOVY0b1U4eVorZWpVdXFJU2NqWk91VitTVEhSV2sxZW5D?= =?utf-8?B?ZjVjeEhseUFoc2ZobGg0VzBkVDhrbzVud0pCRHNZUHJBa2FtRVM4NFFSeHNM?= =?utf-8?B?WEpqT2E0UFFQTmJQTlJhZk1MU0t3N2piQUVGT2I3bFR2c0l6a0ljdjF3Zktz?= =?utf-8?B?bTZjV2gxa1EzRXBjRXlGT1VSVGVQM3ZIMSsyOXIwbDNUVXdUUUd5VzhYaUJI?= =?utf-8?B?cGc0bDQ0c0IyenJUR01LajZPdjJ0YTllUnEwbHp2NDFLelIrV1k2RlI4RTJL?= =?utf-8?B?OG00QldIdFR2Q3FLSlNaOGV1VTlYNFJFMm8rTlhjWXc4OEs5b0NtV0pWbTl1?= =?utf-8?B?aGpEZEovSEp5UDFic2Q2NlgvUXV1eTI1ZjBpNXhSYjVxTGNoUkJ2WXhTZ3Iv?= =?utf-8?B?a1BBVS95ZUFWY0VuWnJHSzBNeXQyUTgyZmE4b2dyaVFPWmVoNWVYdVB3Mi9r?= =?utf-8?B?cTZvc0lHV1pqUjF0MUtCejAxK1ZESjlKRFBRMUx6TFBZcG1xUXROdXhtZHgz?= =?utf-8?B?MnZyc1lIZktJSHhOczRxaTJhQ1RZSFJ3SlBNQlA4cTFxdFFnMkZzVzFoVkNQ?= =?utf-8?B?TjRwRG13dGlJYVZFdzVjVzZLMTNUNzZzNWpibHgvcU5BMXZGVDNKMWpkSDRP?= =?utf-8?B?NTJxQk40Q3lIL1pDR3YvVWxyZ0VuRWRpV0JDVEliSjJEdkRWQ1h0MzNHSHlt?= =?utf-8?B?eE80VXhXWVhHcnVkYkMwTlUwOVIyQ05vSjh6MzBFZlVMS1E1Y3VqVVFvQWU3?= =?utf-8?B?RkM2TnNvQnFaa3pXUVNzUVE1cm9yU2JTYjN6aFBCeXByUy9pMGY2VGJ6MEJv?= =?utf-8?B?K24zNGordmNWcHVFWno5QXFLU2h6Y1lQaU16TkFLYmpnamZVbkhueXJjRWpE?= =?utf-8?B?VjN3QmhLLzlnL0pvbGFxaGl0YTdiME1VaTNPSHVtenFhTk42VXJ3NlV3Unl3?= =?utf-8?B?blRwK2J5dlJHUFgrWk5SS2ZHd2NOTDM2UEZjUFdBSUNRc3J3RVNWTzBPbGhR?= =?utf-8?B?ejF1KzgrNlpXUUoxMWpsU3lZVFdnMWhJR2RIT0JpZjhXekVzR2toNzhnWHJT?= =?utf-8?B?V2NrT25teEV2Wit1SUFxRndTSFVJa1JaeGJwYjhkMVd1bGU2dDdpSDFOZE90?= =?utf-8?B?OEVCVlVjRkZTWWpRaURISkZQekh3eHhicUdHTUU3U0Z2TC92Nzc2Zk0wZ29j?= =?utf-8?B?UkJEUWl1RXdrbUhHSU9zZ2dRZlgwenFidGlNTENPemNpcEdFb3B3V2RBbnVn?= =?utf-8?B?ZERtREtZaXFpZjFyb2pCVlNPRmYxYVpDRUU4R010a3NlWFZSb2c5WGd2Vzhw?= =?utf-8?B?enpzRlRqUmVMcXlKKzBZMGd4WFZlUGlYRnlYdllFanovcTNnd1FoNDVjTXlY?= =?utf-8?B?VGk1cy95enJ4RHVCbGEyT2dXcnExaDVZdGdUTTROVm5GMW1pSDRTcXdhVkNp?= =?utf-8?B?ZU42T1UyWlo1dXVVZG9TMUZlR0VMbmh0Y3JLVkdJMHVUZ3czUWl4aHdHT09U?= =?utf-8?B?LytwVTFXODV1TVpSejZoajZXcDhXNjBxeFYxZlZUalJtaldrMXdrQT09?= X-OriginatorOrg: garyguo.net X-MS-Exchange-CrossTenant-Network-Message-Id: 20c14eb5-955c-4b80-36ba-08dee748bf6b X-MS-Exchange-CrossTenant-AuthSource: LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jul 2026 16:54:36.8807 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bbc898ad-b10f-4e10-8552-d9377b823d45 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: tGvR0kvCcFhqn7q+ZNM+SVDB8Lt3QZy3D+KJwVX05hhUp13TU1sIbdlD63YybN7XJWzW+bUe56xz32SlepeIOQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LO8P265MB7878 Add a helper function that allows obtaining a subregion from region with compile-time check. This can be used by drivers to obtaining a subregion for relative register access. Signed-off-by: Gary Guo --- rust/kernel/io.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs index 0f8b166a6d3b..f31d37c8a3d5 100644 --- a/rust/kernel/io.rs +++ b/rust/kernel/io.rs @@ -80,6 +80,30 @@ pub fn ptr_try_from_raw_parts_mut(base: *mut u8, size: u= size) -> Result<*mut Sel =20 Ok(Self::ptr_from_raw_parts_mut(base, size)) } + + /// Create a subregion with provided offset and size. + #[inline] + pub fn subregion<'a, const OFFSET: usize, const NEW_SIZE: usize, IO>( + io: IO, + ) -> ::View<'a, Region> + where + IO: IoBase<'a, Target =3D Self>, + { + const_assert!( + OFFSET + NEW_SIZE <=3D SIZE && OFFSET.is_multiple_of(4) && NEW= _SIZE.is_multiple_of(4) + ); + + let view =3D io.as_view(); + let ptr =3D IO::Backend::as_ptr(view) as *mut [u8]; + let new_ptr =3D Region::ptr_from_raw_parts_mut( + ptr.cast::().wrapping_add(OFFSET), + ptr.len() - OFFSET, + ); + + // SAFETY: We have checked that the new region is a subregion and = it is aligned, hence it is + // a valid projection. + unsafe { IO::Backend::project_view(view, new_ptr) } + } } =20 impl KnownSize for Region { --=20 2.54.0 From nobody Sat Jul 25 00:16:38 2026 Received: from CWXP265CU009.outbound.protection.outlook.com (mail-ukwestazon11021132.outbound.protection.outlook.com [52.101.100.132]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EF4673AEB5C; Tue, 21 Jul 2026 16:54:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.100.132 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652892; cv=fail; b=KFP/tEa6WhwgG4vFrmwmd/VFfmJ+2BdsJ9FbZKLNVYZDgNRrBSCj/iJnbOb/HLV9cHHGeLKxtBaAmGjkj5Gn8xsnkety6y8M3eRssqK+HqV4cE6Q7rowdrPQHE+C3OTRgSA+BBmMOgzntWy7UYVIety7u3skwG18MI3IsZZT++c= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652892; c=relaxed/simple; bh=nOV0ISgyzzax+jzHJde42WVYoL+NI8pIw7tEdedWISc=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=ZYm8bvnans9l5f10Rqq5/gkfl4IKZ279g/9Abit8gzi+kDKgEUzKXxlR1uWHMSQy+VBTOe/C9g/sBUdZmUjxoZm6fx1dcUvcCDxbq2lbwGJMaZHDpOj57c9p2Kmu+e9iNN/f/ovuWVuU8DvGXu6EOBXGNuRuheu0zTC9BauEKzs= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net; spf=pass smtp.mailfrom=garyguo.net; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b=H1I6F0lJ; arc=fail smtp.client-ip=52.101.100.132 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=garyguo.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b="H1I6F0lJ" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=vJrQkfpGsecSd+7bJzUKCGrVeO7egrkbzMVjCzVczLqIiUZBQUQq10GDOOihoMRj3gFrjlndK1jetAVMnoD95WfuetN9bDEEXMXPI90zALH0nk6x4Yh6QMwN62iHoasTBM1Q0wN6f8oQFq0/xl847A0RfEde06C7fzHxmeZs2zpqfyi76q2WSBfh/W1HGFRchCxge6juXVvYe7ewmdbh1PcZgT5cU+kxvxcegoIqk6g6i087/rFbKIeUnKvjmcfxuKMkHaE3gXfHJ3SdTDNLV3I7N+PK1WXKfkHX9A3qX2o7r4Ah+leBI8xdg3UVAM+1wplfeHH3QhxW9mi8x5bFEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Jcr+U5Mxse2jgojKiXRGKCtxnArv5kZ0sYs+hWuSudg=; b=tuUmgqS8Ko4seSXtyn0+VvBG1JIfBhi47K85d2OuTVBpmG/MdOVCThiwqZ9BRgwiCI8rk3F+i+DTDcLk5TaDG6xq613QfzZUFiW/sJ3/0X+j1tsKmywFs4H/XXKQbwdz70x1YK9BawCKSSmciSBAno6A4vQJ9Q0+4ACNXw1bXV9XVLU5bSQrO4bPcL/z0cFEejtHaybvQr+VkZ2mkuIqhGHi9m2HeIa2zC6oDmbNNJrFyqHq451zv0Xi2KgHJG4XerpT7qtLE9pg7BHqf2dcxFr8cG+ZPTV6SJFkGgtx33hDdjL04XaGnuiPOMXCzXNQtu7VBg9d5NoKjXEA4CgOng== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=garyguo.net; dmarc=pass action=none header.from=garyguo.net; dkim=pass header.d=garyguo.net; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=garyguo.net; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Jcr+U5Mxse2jgojKiXRGKCtxnArv5kZ0sYs+hWuSudg=; b=H1I6F0lJFCpliK0wdCLoF2iUjvJMkwX0WpEhHKBQVThk277ZMdBm3LDs+BT7RWa8UNW57dzAh2jiETkZGEe03jRg55Q2ydKp8BoIhqArP9BiwoEWVl6l7HT3Xz6Pbh5BazUklHLMkfWwoNfFtyzhvIrN+JQdbBwPukGm0E07Udk= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=garyguo.net; Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) by LO8P265MB7878.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:3ae::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Tue, 21 Jul 2026 16:54:37 +0000 Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986]) by LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986%4]) with mapi id 15.21.0223.017; Tue, 21 Jul 2026 16:54:37 +0000 From: Gary Guo Date: Tue, 21 Jul 2026 17:54:32 +0100 Subject: [PATCH 08/10] gpu: nova-core: use projection for PFALCON and PFALCON2 registers Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-typed_register-v1-8-452d72b60262@garyguo.net> References: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> In-Reply-To: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> To: Danilo Krummrich , Alice Ryhl , Daniel Almeida , Miguel Ojeda , Boqun Feng , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , David Airlie , Simona Vetter , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= Cc: driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, linux-pci@vger.kernel.org, Gary Guo X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784652872; l=39936; i=gary@garyguo.net; s=20221204; h=from:subject:message-id; bh=nOV0ISgyzzax+jzHJde42WVYoL+NI8pIw7tEdedWISc=; b=n9Kf9oKtZaUENh8xiYPp3EwsVEWpdKOHG+9ZtVME1/XWOGBefvMLRZLZmb//G+krgJZaVxFkt PXDJBw8sLs0AltioZnfKdqQxkC5c8RKPF5gapQRuGeZZU+hMTXiDK36 X-Developer-Key: i=gary@garyguo.net; a=ed25519; pk=vB3uIX95SM4eVrIqo1DWNWKDKD2xzB+yLLLr0yOPYMo= X-ClientProxiedBy: LO4P123CA0143.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:193::22) To LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LOVP265MB8871:EE_|LO8P265MB7878:EE_ X-MS-Office365-Filtering-Correlation-Id: ab991e26-64fe-4371-5e86-08dee748bfb9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|7416014|10070799003|1800799024|366016|56012099006|10067099003|3023799007|22082099003|18002099003|921020; X-Microsoft-Antispam-Message-Info: ZED3mL/NPiL/AcLImy1kXih0rOA7wEMcRyH3hFLbr+ahhXEzHIqserBA6pXrNOv4DuveoAGwfz4yopQ7+u9lj5vAojSsHRiZ6Wahc8JJ8ua7+dqC6Dc9Nximoq+dNdAB64Sj44k8oQdA5ruTB87zhuapmFSkd4FHxYwyKTU/oxGcbXe3TTLKkvCQDd9L8wh57pm3afsk0k74fOYWSXjPH856cX6s43LvODrkum51NOIHifCmN7hlixC14jnusPL47dnlT2nbhWIN2tPIw69jpH/GQRd05433gJzeQEiTHGwyTeKHt/rsTl5GbZNJpWYjW+KCdIGM2NqFJE+bHz5SgtLUaMuLjLC8G3ZBV6UFFcn4IVQ8tTv5PZYuj+1m0DnyP9lXQVW1QdA85NFRqjNqcAMNMu92jhdXZuU7cB0SDVr/NyKhuT+ociFPW9bYjHl57quKGg7yFquDk9yr9BJzauh3CsQEgJYqUqKx32QszxQsaulsn0NKWlUmQ2T1mMlUyjts02JFGafLF7LAjT61lmwTOlYebvQC1fBu01XGTAES+bkVbhb5OfflnQm7s3F+qTagbDyeySL2LKflay+Ed+j1pJFcyEjYmmYc6v9Wt2ND2ol+uWuofAqNflmDfbNOev/diBXIB6vOwTaGadQdeLL11Z3aUf83WUE4SG1v+6J4fVuWI238O7jfOjNRu+W86XohM7EXpYxQJFFtbaeNUQ== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(376014)(7416014)(10070799003)(1800799024)(366016)(56012099006)(10067099003)(3023799007)(22082099003)(18002099003)(921020);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?ZmRTRHQ1emk1NTlaTUNuNFJnN3Z5QnNRelMyekdDVVllWmtHWElsUE9HblRT?= =?utf-8?B?SVd3YUFIL25wYzgwQ2N4VExWMWUwaEV2UlpkSmZrd1kvOTBDT1JDbmttT3pn?= =?utf-8?B?V3BUS3FDQWZ5RW5mNlIvbEt4cTdGc25udUV0Qm9rbGZzSnJCTG9kTXZwR1Ax?= =?utf-8?B?VlBCNWZuZGVRcnhHRThQVlRPNDgzem9CdUxVVlVDVWdOVStCMkd5aWtmaWY3?= =?utf-8?B?L2h2QUN0a0phbFRsdlF3dDJ5R3ppaUpWL0VXeDYxN01kNHFTQnhrMjlXdU9N?= =?utf-8?B?YnJUWmtyL0RrcWFGQ2kyYlNCa052M0FlVTgybXR6eU9Qd01TdnFwTUorb0N5?= =?utf-8?B?R09mUm4vRFNpRERFZmVoek9SUFJoQ29Bb3BWcnhwQXhBeGhTNWVydTVqajU1?= =?utf-8?B?VGFER0pNN0pWcGJTUjlxUGozd2FrVzlTNTlCbnZ6Tm5XZ1M5UDJoTFdDR2Na?= =?utf-8?B?OGN6ako3VlkrTVVBaXNkU1dTMXdDcG54dHN5R2NaYTNmemEwcUFhUUZLMDVG?= =?utf-8?B?NzdyTTlRTk1xYWhaalBiTmRCRHFhTVEyWTJueWVCRkJGem1yYmMxVi8zOGdx?= =?utf-8?B?a1J0L1MzVEo5b1lPZlJzV280eituVjc1RG9vY1VZWDU5dzRaOEdTdFFwYmtZ?= =?utf-8?B?ZEU4aVNZOEZ0RkJGblo2MlJ4ZmtEUkRIbnhGS0tidmlISk9pN25ycDRicTNM?= =?utf-8?B?M0MrNDBvMzQzVlFSN1hFSFVDN1BHK2hPbHgyOUFCTW1VWlp2RTBGQ0NaK2xm?= =?utf-8?B?UFNsYmRlVUxrdHp4SnoydmF4L0pvUVJzMjJpNE4yMXk4UTR6VmVzbnVRRmh3?= =?utf-8?B?UmcrbzdPQXZNdWVTZEgwTGZtNjFkczA2T214REY1cThmSXpvUGJUWjNETkl4?= =?utf-8?B?YzMvV0IvQzFxdWFUYkRUUXMwaHdMMWZLNWE1KzA4YXRhazI2VXlldVlvc1Fr?= =?utf-8?B?NUwyQ01ONFdzOENvNitEWCtuZi9IMzNWMFlWOXo3UjVlWCtRNlB2dU1qUmVz?= =?utf-8?B?Wmw2d2VSYnpzNHhPWVluS3l6NnM5VTgxaTc3L3JrMk14MUpuRDNWUm9WUVNm?= =?utf-8?B?amJyYm9PcTFSN3RoQkh6eXEzQkF0S21jSDZYODVkc2JQS09McEVETmV6RFdT?= =?utf-8?B?T2RBU09XclhTczFrY3k5L1J6ZkUwS1F5NWNHdGNER3hUOXNUVmI5Tk5nYTFM?= =?utf-8?B?WEFIR3FNVGZVdytneXEwR2F5NmdxNjFhdXpFUHNFOW02UmNYclYwbTlyMFJB?= =?utf-8?B?RHB0ell1NzZ3bThzVDFHd2tnVHN2VnlaSUc3dUNhNkFMSWNqNHBjak1MNm1Z?= =?utf-8?B?UVJ5eDg4Umxwb0c3ZVk0YTlJb0NkQ0JLNXpadURjM0Vhb0N4K0VKdmRaZUJZ?= =?utf-8?B?VDNyWlI2akd2UHVNNy9DUEpMQ1ZOYU9KdlVuQVZHc2JEOTlla2RtWldHd3lw?= =?utf-8?B?Z29OZ041LzFJVGl4MGVweldaT0YyUVcxbHJkbkpFYVpFSCtVQkM5VEZFcEFN?= =?utf-8?B?emRoby8rRUdTQWxxU0pLdCs0azBMcU9oam1vZkxxekN6TmlQT1pNQ1ZGemZa?= =?utf-8?B?RDZVTFF2cTQyTHlIT0p6cGdLeWFnTUM2L1FSN2VEZG5SMW1IVWhVZTAvU2NQ?= =?utf-8?B?eDR3eFdyL283dkZaV3ZMZkpBUTE5S04zclJqbXBYMCtqSXR2WFgxbGdEbXJs?= =?utf-8?B?THdLMzB1TUt1bWJMVDUwdHErS0VzUFZ1dDFET1crWFkrVERyL3dvZ0Mxbm5C?= =?utf-8?B?emNNQmV6UVpZUExDZ1lyTVdqYmlES0UzVUN6S0Q4SWltaVdvRnpKMHZBSDg0?= =?utf-8?B?QmlKaWV2SkZOclVZZXBtdUtXQzRiQ2FPZmtrdy95cytkSCt0VGd1N0hLeDE1?= =?utf-8?B?alpNbFJtRjVmYWx2MEZOOS9BQ01rcWJQdE0xbEV1SGdzSFNHTXF2THVlVllD?= =?utf-8?B?ZTdZTys0WFkwTXBMTEVYWkpsNUlhWjZNeElNbDBBY3FuS2dsSldtUVdrNnQr?= =?utf-8?B?MHcvVE91cGdUMjMvWDUyMTRSSWw1NG4rSmhicDRnQTA0ZHlkZlU1NWV0TEJn?= =?utf-8?B?NkRkdUhlU0lCbkhDMllMaTBqVDlicDFqcnhkWTkxKytZVHpzVGxoTXVzVy9x?= =?utf-8?B?dE9ab0VSaU0wOG9ISTFyeFZyUVg3SklucDQxK2QyRFpuYzRreCtUTWdubDVJ?= =?utf-8?B?QW1LdGUwNkhPQlA3QmhUbkVKMFRkWFVpZlJySFNURmhMSDJNOVczakxMaVJj?= =?utf-8?B?b1JCQ1N0QTFvOXNoYzZueWF6WVpxODMvamtyeE4xWmZvekdscC9weTlWV0Fq?= =?utf-8?B?bnhqa2RRMyttYm5lbGVSRytvdEltYjlzb2ZvRVhLYzhFYVpNcElHUT09?= X-OriginatorOrg: garyguo.net X-MS-Exchange-CrossTenant-Network-Message-Id: ab991e26-64fe-4371-5e86-08dee748bfb9 X-MS-Exchange-CrossTenant-AuthSource: LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jul 2026 16:54:37.4188 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bbc898ad-b10f-4e10-8552-d9377b823d45 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: IgVhclryOkbaHNq6RqAczchIU9Ub+gPiiQH3uXtxHO/6mcd4xW+1hvbKzGptUWhcM/PhPNDF7v0oTbNYcAodfQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LO8P265MB7878 Add fixed size region types for these and add projection methods that project from `Bar0` into these. Update these registers to be registers on `PFalconRegisters` and `PFalcon2Registers` and not relative registers on `NovaRegisters`. The use sites are updated mechanically; calls to the projection methods are not extracted in this commit. Signed-off-by: Gary Guo --- drivers/gpu/nova-core/falcon.rs | 158 +++++++++--------= ---- drivers/gpu/nova-core/falcon/fsp.rs | 53 +++---- drivers/gpu/nova-core/falcon/gsp.rs | 43 +++--- drivers/gpu/nova-core/falcon/hal/ga102.rs | 39 ++--- drivers/gpu/nova-core/falcon/hal/tu102.rs | 8 +- drivers/gpu/nova-core/falcon/sec2.rs | 32 +++-- drivers/gpu/nova-core/firmware/fwsec/bootloader.rs | 11 +- drivers/gpu/nova-core/regs.rs | 81 ++++++----- 8 files changed, 193 insertions(+), 232 deletions(-) diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon= .rs index 78948cc8bff3..3cd065019a66 100644 --- a/drivers/gpu/nova-core/falcon.rs +++ b/drivers/gpu/nova-core/falcon.rs @@ -14,13 +14,12 @@ }, io::{ poll::read_poll_timeout, - register::{ - RegisterBase, - WithBase, // - }, + register::Array, Io, + Mmio, // }, prelude::*, + sizes::SZ_4K, time::Delta, }; =20 @@ -165,18 +164,22 @@ pub(crate) enum FalconFbifMemType with From> { } } =20 -/// Type used to represent the `PFALCON` registers address base for a give= n falcon engine. -pub(crate) struct PFalconBase(()); +/// Type used to represent the `PFALCON` registers. +#[repr(align(4))] +#[derive(FromBytes, IntoBytes)] +pub(crate) struct PFalconRegisters([u8; SZ_4K]); =20 -/// Type used to represent the `PFALCON2` registers address base for a giv= en falcon engine. -pub(crate) struct PFalcon2Base(()); +/// Type used to represent the `PFALCON2` registers. +#[repr(align(4))] +#[derive(FromBytes, IntoBytes)] +pub(crate) struct PFalcon2Registers([u8; SZ_4K]); =20 /// Trait defining the parameters of a given Falcon engine. /// /// Each engine provides one base for `PFALCON` and `PFALCON2` registers. -pub(crate) trait FalconEngine: - Send + Sync + RegisterBase + RegisterBase += Sized -{ +pub(crate) trait FalconEngine: Send + Sync + Sized { + fn pfalcon(io: Bar0<'_>) -> Mmio<'_, PFalconRegisters>; + fn pfalcon2(io: Bar0<'_>) -> Mmio<'_, PFalcon2Registers>; } =20 /// Represents a portion of the firmware to be loaded into a particular me= mory (e.g. IMEM or DMEM) @@ -376,14 +379,11 @@ pub(crate) fn new( =20 /// Resets DMA-related registers. pub(crate) fn dma_reset(&self) { - self.bar.update(regs::NV_PFALCON_FBIF_CTL::of::(), |v| { + E::pfalcon(self.bar).update(regs::NV_PFALCON_FBIF_CTL, |v| { v.with_allow_phys_no_ctx(true) }); =20 - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_DMACTL::zeroed(), - ); + E::pfalcon(self.bar).write_reg(regs::NV_PFALCON_FALCON_DMACTL::zer= oed()); } =20 /// Reset the controller, select the falcon core, and wait for memory = scrubbing to complete. @@ -392,10 +392,9 @@ pub(crate) fn reset(&self) -> Result { self.hal.select_core(self)?; self.hal.reset_wait_mem_scrubbing(self)?; =20 - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_RM::from(self.bar.read(regs::NV_PMC_BO= OT_0).into_raw()), - ); + E::pfalcon(self.bar).write_reg(regs::NV_PFALCON_FALCON_RM::from( + self.bar.read(regs::NV_PMC_BOOT_0).into_raw(), + )); =20 Ok(()) } @@ -413,8 +412,8 @@ fn pio_wr_imem_slice(&self, load_offsets: FalconPioImem= LoadTarget<'_>) -> Result return Err(EINVAL); } =20 - self.bar.write( - WithBase::of::().at(Self::PIO_PORT), + E::pfalcon(self.bar).write( + Array::at(Self::PIO_PORT), regs::NV_PFALCON_FALCON_IMEMC::zeroed() .with_secure(load_offsets.secure) .with_aincw(true) @@ -424,14 +423,14 @@ fn pio_wr_imem_slice(&self, load_offsets: FalconPioIm= emLoadTarget<'_>) -> Result for (n, block) in load_offsets.data.chunks(MEM_BLOCK_ALIGNMENT).en= umerate() { let n =3D u16::try_from(n)?; let tag: u16 =3D load_offsets.start_tag.checked_add(n).ok_or(E= RANGE)?; - self.bar.write( - WithBase::of::().at(Self::PIO_PORT), + E::pfalcon(self.bar).write( + Array::at(Self::PIO_PORT), regs::NV_PFALCON_FALCON_IMEMT::zeroed().with_tag(tag), ); for word in block.chunks_exact(4) { let w =3D [word[0], word[1], word[2], word[3]]; - self.bar.write( - WithBase::of::().at(Self::PIO_PORT), + E::pfalcon(self.bar).write( + Array::at(Self::PIO_PORT), regs::NV_PFALCON_FALCON_IMEMD::zeroed().with_data(u32:= :from_le_bytes(w)), ); } @@ -450,8 +449,8 @@ fn pio_wr_dmem_slice(&self, load_offsets: FalconPioDmem= LoadTarget<'_>) -> Result return Err(EINVAL); } =20 - self.bar.write( - WithBase::of::().at(Self::PIO_PORT), + E::pfalcon(self.bar).write( + Array::at(Self::PIO_PORT), regs::NV_PFALCON_FALCON_DMEMC::zeroed() .with_aincw(true) .with_offs(load_offsets.dst_start), @@ -459,8 +458,8 @@ fn pio_wr_dmem_slice(&self, load_offsets: FalconPioDmem= LoadTarget<'_>) -> Result =20 for word in load_offsets.data.chunks_exact(4) { let w =3D [word[0], word[1], word[2], word[3]]; - self.bar.write( - WithBase::of::().at(Self::PIO_PORT), + E::pfalcon(self.bar).write( + Array::at(Self::PIO_PORT), regs::NV_PFALCON_FALCON_DMEMD::zeroed().with_data(u32::fro= m_le_bytes(w)), ); } @@ -473,14 +472,11 @@ pub(crate) fn pio_load + FalconPioLoadable>( &self, fw: &F, ) -> Result { - self.bar.update(regs::NV_PFALCON_FBIF_CTL::of::(), |v| { + E::pfalcon(self.bar).update(regs::NV_PFALCON_FBIF_CTL, |v| { v.with_allow_phys_no_ctx(true) }); =20 - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_DMACTL::zeroed(), - ); + E::pfalcon(self.bar).write_reg(regs::NV_PFALCON_FALCON_DMACTL::zer= oed()); =20 if let Some(imem_ns) =3D fw.imem_ns_load_params() { self.pio_wr_imem_slice(imem_ns)?; @@ -492,10 +488,8 @@ pub(crate) fn pio_load= + FalconPioLoadable>( =20 self.hal.program_brom(self, &fw.brom_params()); =20 - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_BOOTVEC::zeroed().with_value(fw.boot_a= ddr()), - ); + E::pfalcon(self.bar) + .write_reg(regs::NV_PFALCON_FALCON_BOOTVEC::zeroed().with_valu= e(fw.boot_addr())); =20 Ok(()) } @@ -563,16 +557,12 @@ fn dma_wr( =20 // Set up the base source DMA address. =20 - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_DMATRFBASE::zeroed().with_base( - // CAST: `as u32` is used on purpose since we do want to s= trip the upper bits, - // which will be written to `NV_PFALCON_FALCON_DMATRFBASE1= `. - (dma_start >> 8) as u32, - ), - ); - self.bar.write( - WithBase::of::(), + E::pfalcon(self.bar).write_reg(regs::NV_PFALCON_FALCON_DMATRFBASE:= :zeroed().with_base( + // CAST: `as u32` is used on purpose since we do want to strip= the upper bits, + // which will be written to `NV_PFALCON_FALCON_DMATRFBASE1`. + (dma_start >> 8) as u32, + )); + E::pfalcon(self.bar).write_reg( regs::NV_PFALCON_FALCON_DMATRFBASE1::zeroed().try_with_base(dm= a_start >> 40)?, ); =20 @@ -582,23 +572,21 @@ fn dma_wr( =20 for pos in (0..num_transfers).map(|i| i * DMA_LEN) { // Perform a transfer of size `DMA_LEN`. - self.bar.write( - WithBase::of::(), + E::pfalcon(self.bar).write_reg( regs::NV_PFALCON_FALCON_DMATRFMOFFS::zeroed() .try_with_offs(load_offsets.dst_start + pos)?, ); - self.bar.write( - WithBase::of::(), + E::pfalcon(self.bar).write_reg( regs::NV_PFALCON_FALCON_DMATRFFBOFFS::zeroed().with_offs(s= rc_start + pos), ); =20 - self.bar.write(WithBase::of::(), cmd); + E::pfalcon(self.bar).write_reg(cmd); =20 // Wait for the transfer to complete. // TIMEOUT: arbitrarily large value, no DMA transfer to the fa= lcon's small memories // should ever take that long. read_poll_timeout( - || Ok(self.bar.read(regs::NV_PFALCON_FALCON_DMATRFCMD::of:= :())), + || Ok(E::pfalcon(self.bar).read(regs::NV_PFALCON_FALCON_DM= ATRFCMD)), |r| r.idle(), Delta::ZERO, Delta::from_secs(2), @@ -630,11 +618,10 @@ fn dma_load + FalconD= maLoadable>(&self, fw: &F) -> }; =20 self.dma_reset(); - self.bar - .update(regs::NV_PFALCON_FBIF_TRANSCFG::of::().at(0), |v| { - v.with_target(FalconFbifTarget::CoherentSysmem) - .with_mem_type(FalconFbifMemType::Physical) - }); + E::pfalcon(self.bar).update(regs::NV_PFALCON_FBIF_TRANSCFG::at(0),= |v| { + v.with_target(FalconFbifTarget::CoherentSysmem) + .with_mem_type(FalconFbifMemType::Physical) + }); =20 self.dma_wr(&dma_obj, FalconMem::ImemSecure, fw.imem_sec_load_para= ms())?; self.dma_wr(&dma_obj, FalconMem::Dmem, fw.dmem_load_params())?; @@ -642,10 +629,8 @@ fn dma_load + FalconDm= aLoadable>(&self, fw: &F) -> self.hal.program_brom(self, &fw.brom_params()); =20 // Set `BootVec` to start of non-secure code. - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_BOOTVEC::zeroed().with_value(fw.boot_a= ddr()), - ); + E::pfalcon(self.bar) + .write_reg(regs::NV_PFALCON_FALCON_BOOTVEC::zeroed().with_valu= e(fw.boot_addr())); =20 Ok(()) } @@ -654,7 +639,7 @@ fn dma_load + FalconDma= Loadable>(&self, fw: &F) -> pub(crate) fn wait_till_halted(&self) -> Result<()> { // TIMEOUT: arbitrarily large value, firmwares should complete in = less than 2 seconds. read_poll_timeout( - || Ok(self.bar.read(regs::NV_PFALCON_FALCON_CPUCTL::of::())= ), + || Ok(E::pfalcon(self.bar).read(regs::NV_PFALCON_FALCON_CPUCTL= )), |r| r.halted(), Delta::ZERO, Delta::from_secs(2), @@ -665,19 +650,14 @@ pub(crate) fn wait_till_halted(&self) -> Result<()> { =20 /// Start the falcon CPU. pub(crate) fn start(&self) -> Result<()> { - match self - .bar - .read(regs::NV_PFALCON_FALCON_CPUCTL::of::()) + match E::pfalcon(self.bar) + .read(regs::NV_PFALCON_FALCON_CPUCTL) .alias_en() { - true =3D> self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_CPUCTL_ALIAS::zeroed().with_startc= pu(true), - ), - false =3D> self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_CPUCTL::zeroed().with_startcpu(tru= e), - ), + true =3D> E::pfalcon(self.bar) + .write_reg(regs::NV_PFALCON_FALCON_CPUCTL_ALIAS::zeroed().= with_startcpu(true)), + false =3D> E::pfalcon(self.bar) + .write_reg(regs::NV_PFALCON_FALCON_CPUCTL::zeroed().with_s= tartcpu(true)), } =20 Ok(()) @@ -686,31 +666,27 @@ pub(crate) fn start(&self) -> Result<()> { /// Writes values to the mailbox registers if provided. pub(crate) fn write_mailboxes(&self, mbox0: Option, mbox1: Option= ) { if let Some(mbox0) =3D mbox0 { - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_MAILBOX0::zeroed().with_value(mbox= 0), - ); + E::pfalcon(self.bar) + .write_reg(regs::NV_PFALCON_FALCON_MAILBOX0::zeroed().with= _value(mbox0)); } =20 if let Some(mbox1) =3D mbox1 { - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_MAILBOX1::zeroed().with_value(mbox= 1), - ); + E::pfalcon(self.bar) + .write_reg(regs::NV_PFALCON_FALCON_MAILBOX1::zeroed().with= _value(mbox1)); } } =20 /// Reads the value from `mbox0` register. pub(crate) fn read_mailbox0(&self) -> u32 { - self.bar - .read(regs::NV_PFALCON_FALCON_MAILBOX0::of::()) + E::pfalcon(self.bar) + .read(regs::NV_PFALCON_FALCON_MAILBOX0) .value() } =20 /// Reads the value from `mbox1` register. pub(crate) fn read_mailbox1(&self) -> u32 { - self.bar - .read(regs::NV_PFALCON_FALCON_MAILBOX1::of::()) + E::pfalcon(self.bar) + .read(regs::NV_PFALCON_FALCON_MAILBOX1) .value() } =20 @@ -765,9 +741,7 @@ pub(crate) fn load + Fa= lconDmaLoadable>(&self, fw: =20 /// Write the application version to the OS register. pub(crate) fn write_os_version(&self, app_version: u32) { - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_OS::zeroed().with_value(app_version), - ); + E::pfalcon(self.bar) + .write_reg(regs::NV_PFALCON_FALCON_OS::zeroed().with_value(app= _version)); } } diff --git a/drivers/gpu/nova-core/falcon/fsp.rs b/drivers/gpu/nova-core/fa= lcon/fsp.rs index 53b1079843ae..cf22992e6387 100644 --- a/drivers/gpu/nova-core/falcon/fsp.rs +++ b/drivers/gpu/nova-core/falcon/fsp.rs @@ -9,23 +9,21 @@ use kernel::{ io::{ poll::read_poll_timeout, - register::{ - Array, - RegisterBase, - WithBase, // - }, - Io, // + register::Array, + Io, + Mmio, + Region, // }, prelude::*, + sizes::SZ_4K, time::Delta, }; =20 use crate::{ + driver::Bar0, falcon::{ Falcon, - FalconEngine, - PFalcon2Base, - PFalconBase, // + FalconEngine, // }, num, regs, // @@ -37,16 +35,18 @@ /// Type specifying the `Fsp` falcon engine. Cannot be instantiated. pub(crate) struct Fsp(()); =20 -impl RegisterBase for Fsp { - const BASE: usize =3D 0x8f2000; -} +impl FalconEngine for Fsp { + #[inline] + fn pfalcon(io: Bar0<'_>) -> Mmio<'_, super::PFalconRegisters> { + Region::subregion::<0x8f2000, SZ_4K, _>(io).cast() + } =20 -impl RegisterBase for Fsp { - const BASE: usize =3D 0x8f3000; + #[inline] + fn pfalcon2(io: Bar0<'_>) -> Mmio<'_, super::PFalcon2Registers> { + Region::subregion::<0x8f3000, SZ_4K, _>(io).cast() + } } =20 -impl FalconEngine for Fsp {} - impl<'a> Falcon<'a, Fsp> { /// Writes `data` to FSP external memory at offset `0`. /// @@ -58,19 +58,14 @@ fn write_emem(&mut self, data: &[u8]) -> Result { } =20 // Begin a write burst at offset `0`, auto-incrementing on each wr= ite. - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_EMEMC::zeroed().with_aincw(true), - ); + Fsp::pfalcon(self.bar).write_reg(regs::NV_PFALCON_FALCON_EMEMC::ze= roed().with_aincw(true)); =20 for chunk in data.chunks_exact(4) { let value =3D u32::from_le_bytes([chunk[0], chunk[1], chunk[2]= , chunk[3]]); =20 // Write the next 32-bit `value`; hardware advances the offset. - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_EMEMD::zeroed().with_data(value), - ); + Fsp::pfalcon(self.bar) + .write_reg(regs::NV_PFALCON_FALCON_EMEMD::zeroed().with_da= ta(value)); } =20 Ok(()) @@ -86,16 +81,12 @@ fn read_emem(&mut self, data: &mut [u8]) -> Result { } =20 // Begin a read burst at offset `0`, auto-incrementing on each rea= d. - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_EMEMC::zeroed().with_aincr(true), - ); + Fsp::pfalcon(self.bar).write_reg(regs::NV_PFALCON_FALCON_EMEMC::ze= roed().with_aincr(true)); =20 for chunk in data.chunks_exact_mut(4) { // Read the next 32-bit word; hardware advances the offset. - let value =3D self - .bar - .read(regs::NV_PFALCON_FALCON_EMEMD::of::()) + let value =3D Fsp::pfalcon(self.bar) + .read(regs::NV_PFALCON_FALCON_EMEMD) .data(); chunk.copy_from_slice(&value.to_le_bytes()); } diff --git a/drivers/gpu/nova-core/falcon/gsp.rs b/drivers/gpu/nova-core/fa= lcon/gsp.rs index ae32f401aeb0..7308c596ad7b 100644 --- a/drivers/gpu/nova-core/falcon/gsp.rs +++ b/drivers/gpu/nova-core/falcon/gsp.rs @@ -3,22 +3,20 @@ use kernel::{ io::{ poll::read_poll_timeout, - register::{ - RegisterBase, - WithBase, // - }, Io, + Mmio, + Region, // }, prelude::*, + sizes::SZ_4K, time::Delta, // }; =20 use crate::{ + driver::Bar0, falcon::{ Falcon, - FalconEngine, - PFalcon2Base, - PFalconBase, // + FalconEngine, // }, regs, }; @@ -26,24 +24,24 @@ /// Type specifying the `Gsp` falcon engine. Cannot be instantiated. pub(crate) struct Gsp(()); =20 -impl RegisterBase for Gsp { - const BASE: usize =3D 0x00110000; -} +impl FalconEngine for Gsp { + #[inline] + fn pfalcon<'a>(io: Bar0<'a>) -> Mmio<'a, super::PFalconRegisters> { + Region::subregion::<0x00110000, SZ_4K, _>(io).cast() + } =20 -impl RegisterBase for Gsp { - const BASE: usize =3D 0x00111000; + #[inline] + fn pfalcon2<'a>(io: Bar0<'a>) -> Mmio<'a, super::PFalcon2Registers> { + Region::subregion::<0x00111000, SZ_4K, _>(io).cast() + } } =20 -impl FalconEngine for Gsp {} - impl<'a> Falcon<'a, Gsp> { /// Clears the SWGEN0 bit in the Falcon's IRQ status clear register to /// allow GSP to signal CPU for processing new messages in message que= ue. pub(crate) fn clear_swgen0_intr(&self) { - self.bar.write( - WithBase::of::(), - regs::NV_PFALCON_FALCON_IRQSCLR::zeroed().with_swgen0(true), - ); + Gsp::pfalcon(self.bar) + .write_reg(regs::NV_PFALCON_FALCON_IRQSCLR::zeroed().with_swge= n0(true)); } =20 /// Checks if GSP reload/resume has completed during the boot process. @@ -59,8 +57,8 @@ pub(crate) fn check_reload_completed(&self, timeout: Delt= a) -> Result { =20 /// Returns whether the RISC-V branch privilege lockdown bit is set. pub(crate) fn riscv_branch_privilege_lockdown(&self) -> bool { - self.bar - .read(regs::NV_PFALCON_FALCON_HWCFG2::of::()) + Gsp::pfalcon(self.bar) + .read(regs::NV_PFALCON_FALCON_HWCFG2) .riscv_br_priv_lockdown() } =20 @@ -71,9 +69,8 @@ pub(crate) fn priv_target_mask_released(&self) -> bool { const LOCKED_PATTERN: u32 =3D 0xbadf_4100; const LOCKED_MASK: u32 =3D 0xffff_ff00; =20 - let hwcfg2 =3D self - .bar - .read(regs::NV_PFALCON_FALCON_HWCFG2::of::()) + let hwcfg2 =3D Gsp::pfalcon(self.bar) + .read(regs::NV_PFALCON_FALCON_HWCFG2) .into_raw(); =20 hwcfg2 !=3D 0 && (hwcfg2 & LOCKED_MASK) !=3D LOCKED_PATTERN diff --git a/drivers/gpu/nova-core/falcon/hal/ga102.rs b/drivers/gpu/nova-c= ore/falcon/hal/ga102.rs index fe821ded5fa1..c0a23a84aa69 100644 --- a/drivers/gpu/nova-core/falcon/hal/ga102.rs +++ b/drivers/gpu/nova-core/falcon/hal/ga102.rs @@ -6,10 +6,7 @@ device, io::{ poll::read_poll_timeout, - register::{ - Array, - WithBase, // - }, + register::Array, Io, // }, prelude::*, @@ -32,16 +29,15 @@ use super::FalconHal; =20 fn select_core_ga102(bar: Bar0<'_>) -> Result { - let bcr_ctrl =3D bar.read(regs::NV_PRISCV_RISCV_BCR_CTRL::of::()); + let bcr_ctrl =3D E::pfalcon2(bar).read(regs::NV_PRISCV_RISCV_BCR_CTRL); if bcr_ctrl.core_select() !=3D PeregrineCoreSelect::Falcon { - bar.write( - WithBase::of::(), + E::pfalcon2(bar).write_reg( regs::NV_PRISCV_RISCV_BCR_CTRL::zeroed().with_core_select(Pere= grineCoreSelect::Falcon), ); =20 // TIMEOUT: falcon core should take less than 10ms to report being= enabled. read_poll_timeout( - || Ok(bar.read(regs::NV_PRISCV_RISCV_BCR_CTRL::of::())), + || Ok(E::pfalcon2(bar).read(regs::NV_PRISCV_RISCV_BCR_CTRL)), |r| r.valid(), Delta::ZERO, Delta::from_millis(10), @@ -87,23 +83,19 @@ fn signature_reg_fuse_version_ga102( } =20 fn program_brom_ga102(bar: Bar0<'_>, params: &FalconBromP= arams) { - bar.write( - WithBase::of::().at(0), + E::pfalcon2(bar).write( + Array::at(0), regs::NV_PFALCON2_FALCON_BROM_PARAADDR::zeroed().with_value(params= .pkc_data_offset), ); - bar.write( - WithBase::of::(), + E::pfalcon2(bar).write_reg( regs::NV_PFALCON2_FALCON_BROM_ENGIDMASK::zeroed() .with_value(u32::from(params.engine_id_mask)), ); - bar.write( - WithBase::of::(), + E::pfalcon2(bar).write_reg( regs::NV_PFALCON2_FALCON_BROM_CURR_UCODE_ID::zeroed().with_ucode_i= d(params.ucode_id), ); - bar.write( - WithBase::of::(), - regs::NV_PFALCON2_FALCON_MOD_SEL::zeroed().with_algo(FalconModSelA= lgo::Rsa3k), - ); + E::pfalcon2(bar) + .write_reg(regs::NV_PFALCON2_FALCON_MOD_SEL::zeroed().with_algo(Fa= lconModSelAlgo::Rsa3k)); } =20 pub(super) struct Ga102(PhantomData); @@ -133,16 +125,15 @@ fn program_brom(&self, falcon: &Falcon<'_, E>, params= : &FalconBromParams) { } =20 fn is_riscv_active(&self, falcon: &Falcon<'_, E>) -> bool { - falcon - .bar - .read(regs::NV_PRISCV_RISCV_CPUCTL::of::()) + E::pfalcon2(falcon.bar) + .read(regs::NV_PRISCV_RISCV_CPUCTL) .active_stat() } =20 fn reset_wait_mem_scrubbing(&self, falcon: &Falcon<'_, E>) -> Result { // TIMEOUT: memory scrubbing should complete in less than 20ms. read_poll_timeout( - || Ok(falcon.bar.read(regs::NV_PFALCON_FALCON_HWCFG2::of::(= ))), + || Ok(E::pfalcon(falcon.bar).read(regs::NV_PFALCON_FALCON_HWCF= G2)), |r| r.mem_scrubbing_done(), Delta::ZERO, Delta::from_millis(20), @@ -153,12 +144,12 @@ fn reset_wait_mem_scrubbing(&self, falcon: &Falcon<'_= , E>) -> Result { fn reset_eng(&self, falcon: &Falcon<'_, E>) -> Result { let bar =3D falcon.bar; =20 - let _ =3D bar.read(regs::NV_PFALCON_FALCON_HWCFG2::of::()); + let _ =3D E::pfalcon(bar).read(regs::NV_PFALCON_FALCON_HWCFG2); =20 // According to OpenRM's `kflcnPreResetWait_GA102` documentation, = HW sometimes does not set // RESET_READY so a non-failing timeout is used. let _ =3D read_poll_timeout( - || Ok(bar.read(regs::NV_PFALCON_FALCON_HWCFG2::of::())), + || Ok(E::pfalcon(bar).read(regs::NV_PFALCON_FALCON_HWCFG2)), |r| r.reset_ready(), Delta::ZERO, Delta::from_micros(150), diff --git a/drivers/gpu/nova-core/falcon/hal/tu102.rs b/drivers/gpu/nova-c= ore/falcon/hal/tu102.rs index 34bf9f3f44c7..23ba22d6a7cf 100644 --- a/drivers/gpu/nova-core/falcon/hal/tu102.rs +++ b/drivers/gpu/nova-core/falcon/hal/tu102.rs @@ -5,7 +5,6 @@ use kernel::{ io::{ poll::read_poll_timeout, - register::WithBase, Io, // }, prelude::*, @@ -49,16 +48,15 @@ fn signature_reg_fuse_version( fn program_brom(&self, _falcon: &Falcon<'_, E>, _params: &FalconBromPa= rams) {} =20 fn is_riscv_active(&self, falcon: &Falcon<'_, E>) -> bool { - falcon - .bar - .read(regs::NV_PRISCV_RISCV_CORE_SWITCH_RISCV_STATUS::of::(= )) + E::pfalcon2(falcon.bar) + .read(regs::NV_PRISCV_RISCV_CORE_SWITCH_RISCV_STATUS) .active_stat() } =20 fn reset_wait_mem_scrubbing(&self, falcon: &Falcon<'_, E>) -> Result { // TIMEOUT: memory scrubbing should complete in less than 10ms. read_poll_timeout( - || Ok(falcon.bar.read(regs::NV_PFALCON_FALCON_DMACTL::of::(= ))), + || Ok(E::pfalcon(falcon.bar).read(regs::NV_PFALCON_FALCON_DMAC= TL)), |r| r.mem_scrubbing_done(), Delta::ZERO, Delta::from_millis(10), diff --git a/drivers/gpu/nova-core/falcon/sec2.rs b/drivers/gpu/nova-core/f= alcon/sec2.rs index 91ec7d49c1f5..5acec63e6394 100644 --- a/drivers/gpu/nova-core/falcon/sec2.rs +++ b/drivers/gpu/nova-core/falcon/sec2.rs @@ -1,22 +1,30 @@ // SPDX-License-Identifier: GPL-2.0 =20 -use kernel::io::register::RegisterBase; +use kernel::{ + io::{ + Io, + Mmio, + Region, // + }, + sizes::SZ_4K, +}; =20 -use crate::falcon::{ - FalconEngine, - PFalcon2Base, - PFalconBase, // +use crate::{ + driver::Bar0, + falcon::FalconEngine, // }; =20 /// Type specifying the `Sec2` falcon engine. Cannot be instantiated. pub(crate) struct Sec2(()); =20 -impl RegisterBase for Sec2 { - const BASE: usize =3D 0x00840000; -} +impl FalconEngine for Sec2 { + #[inline] + fn pfalcon(io: Bar0<'_>) -> Mmio<'_, super::PFalconRegisters> { + Region::subregion::<0x00840000, SZ_4K, _>(io).cast() + } =20 -impl RegisterBase for Sec2 { - const BASE: usize =3D 0x00841000; + #[inline] + fn pfalcon2(io: Bar0<'_>) -> Mmio<'_, super::PFalcon2Registers> { + Region::subregion::<0x00841000, SZ_4K, _>(io).cast() + } } - -impl FalconEngine for Sec2 {} diff --git a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs b/drivers/g= pu/nova-core/firmware/fwsec/bootloader.rs index d9fafd2eea5b..95fec6dd3cfd 100644 --- a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs +++ b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs @@ -12,7 +12,10 @@ Device, // }, dma::Coherent, - io::{register::WithBase, Io}, + io::{ + register::Array, + Io, // + }, prelude::*, ptr::{ Alignable, @@ -33,6 +36,7 @@ Falcon, FalconBromParams, FalconDmaLoadable, + FalconEngine, FalconFbifMemType, FalconFbifTarget, FalconFirmware, @@ -287,9 +291,8 @@ pub(crate) fn run( .inspect_err(|e| dev_err!(dev, "Failed to load FWSEC firmware:= {:?}\n", e))?; =20 // Configure DMA index for the bootloader to fetch the FWSEC firmw= are from system memory. - bar.update( - regs::NV_PFALCON_FBIF_TRANSCFG::of::() - .try_at(usize::from_safe_cast(self.dmem_desc.ctx_dma)) + Gsp::pfalcon(bar).update( + regs::NV_PFALCON_FBIF_TRANSCFG::try_at(usize::from_safe_cast(s= elf.dmem_desc.ctx_dma)) .ok_or(EINVAL)?, |v| { v.with_target(FalconFbifTarget::CoherentSysmem) diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs index f2aadeb429b8..7f7cb84b21e8 100644 --- a/drivers/gpu/nova-core/regs.rs +++ b/drivers/gpu/nova-core/regs.rs @@ -4,7 +4,6 @@ use kernel::{ io::{ register, - register::WithBase, Io, // }, prelude::*, @@ -24,8 +23,8 @@ FalconMem, FalconModSelAlgo, FalconSecurityModel, - PFalcon2Base, - PFalconBase, + PFalcon2Registers, + PFalconRegisters, PeregrineCoreSelect, // }, gpu::{ @@ -339,32 +338,32 @@ pub(crate) fn usable_fb_size(self) -> u64 { // PFALCON =20 register! { - base: NovaRegisters; + base: PFalconRegisters; =20 - pub(crate) NV_PFALCON_FALCON_IRQSCLR(u32) @ PFalconBase + 0x00000004 { + pub(crate) NV_PFALCON_FALCON_IRQSCLR(u32) @ 0x00000004 { 6:6 swgen0 =3D> bool; 4:4 halt =3D> bool; } =20 - pub(crate) NV_PFALCON_FALCON_MAILBOX0(u32) @ PFalconBase + 0x00000040 { + pub(crate) NV_PFALCON_FALCON_MAILBOX0(u32) @ 0x00000040 { 31:0 value =3D> u32; } =20 - pub(crate) NV_PFALCON_FALCON_MAILBOX1(u32) @ PFalconBase + 0x00000044 { + pub(crate) NV_PFALCON_FALCON_MAILBOX1(u32) @ 0x00000044 { 31:0 value =3D> u32; } =20 /// Used to store version information about the firmware running /// on the Falcon processor. - pub(crate) NV_PFALCON_FALCON_OS(u32) @ PFalconBase + 0x00000080 { + pub(crate) NV_PFALCON_FALCON_OS(u32) @ 0x00000080 { 31:0 value =3D> u32; } =20 - pub(crate) NV_PFALCON_FALCON_RM(u32) @ PFalconBase + 0x00000084 { + pub(crate) NV_PFALCON_FALCON_RM(u32) @ 0x00000084 { 31:0 value =3D> u32; } =20 - pub(crate) NV_PFALCON_FALCON_HWCFG2(u32) @ PFalconBase + 0x000000f4 { + pub(crate) NV_PFALCON_FALCON_HWCFG2(u32) @ 0x000000f4 { /// Signal indicating that reset is completed (GA102+). 31:31 reset_ready =3D> bool; /// RISC-V branch privilege lockdown bit. @@ -374,17 +373,17 @@ pub(crate) fn usable_fb_size(self) -> u64 { 10:10 riscv =3D> bool; } =20 - pub(crate) NV_PFALCON_FALCON_CPUCTL(u32) @ PFalconBase + 0x00000100 { + pub(crate) NV_PFALCON_FALCON_CPUCTL(u32) @ 0x00000100 { 6:6 alias_en =3D> bool; 4:4 halted =3D> bool; 1:1 startcpu =3D> bool; } =20 - pub(crate) NV_PFALCON_FALCON_BOOTVEC(u32) @ PFalconBase + 0x00000104 { + pub(crate) NV_PFALCON_FALCON_BOOTVEC(u32) @ 0x00000104 { 31:0 value =3D> u32; } =20 - pub(crate) NV_PFALCON_FALCON_DMACTL(u32) @ PFalconBase + 0x0000010c { + pub(crate) NV_PFALCON_FALCON_DMACTL(u32) @ 0x0000010c { 7:7 secure_stat =3D> bool; 6:3 dmaq_num; 2:2 imem_scrubbing =3D> bool; @@ -392,15 +391,15 @@ pub(crate) fn usable_fb_size(self) -> u64 { 0:0 require_ctx =3D> bool; } =20 - pub(crate) NV_PFALCON_FALCON_DMATRFBASE(u32) @ PFalconBase + 0x0000011= 0 { + pub(crate) NV_PFALCON_FALCON_DMATRFBASE(u32) @ 0x00000110 { 31:0 base =3D> u32; } =20 - pub(crate) NV_PFALCON_FALCON_DMATRFMOFFS(u32) @ PFalconBase + 0x000001= 14 { + pub(crate) NV_PFALCON_FALCON_DMATRFMOFFS(u32) @ 0x00000114 { 23:0 offs; } =20 - pub(crate) NV_PFALCON_FALCON_DMATRFCMD(u32) @ PFalconBase + 0x00000118= { + pub(crate) NV_PFALCON_FALCON_DMATRFCMD(u32) @ 0x00000118 { 16:16 set_dmtag; 14:12 ctxdma; 10:8 size ?=3D> DmaTrfCmdSize; @@ -411,15 +410,15 @@ pub(crate) fn usable_fb_size(self) -> u64 { 0:0 full =3D> bool; } =20 - pub(crate) NV_PFALCON_FALCON_DMATRFFBOFFS(u32) @ PFalconBase + 0x00000= 11c { + pub(crate) NV_PFALCON_FALCON_DMATRFFBOFFS(u32) @ 0x0000011c { 31:0 offs =3D> u32; } =20 - pub(crate) NV_PFALCON_FALCON_DMATRFBASE1(u32) @ PFalconBase + 0x000001= 28 { + pub(crate) NV_PFALCON_FALCON_DMATRFBASE1(u32) @ 0x00000128 { 8:0 base; } =20 - pub(crate) NV_PFALCON_FALCON_HWCFG1(u32) @ PFalconBase + 0x0000012c { + pub(crate) NV_PFALCON_FALCON_HWCFG1(u32) @ 0x0000012c { /// Core revision subversion. 7:6 core_rev_subversion =3D> FalconCoreRevSubversion; /// Security model. @@ -428,12 +427,12 @@ pub(crate) fn usable_fb_size(self) -> u64 { 3:0 core_rev ?=3D> FalconCoreRev; } =20 - pub(crate) NV_PFALCON_FALCON_CPUCTL_ALIAS(u32) @ PFalconBase + 0x00000= 130 { + pub(crate) NV_PFALCON_FALCON_CPUCTL_ALIAS(u32) @ 0x00000130 { 1:1 startcpu =3D> bool; } =20 /// IMEM access control register. Up to 4 ports are available for IMEM= access. - pub(crate) NV_PFALCON_FALCON_IMEMC(u32)[4, stride =3D 16] @ PFalconBas= e + 0x00000180 { + pub(crate) NV_PFALCON_FALCON_IMEMC(u32)[4, stride =3D 16] @ 0x00000180= { /// Access secure IMEM. 28:28 secure =3D> bool; /// Auto-increment on write. @@ -444,17 +443,17 @@ pub(crate) fn usable_fb_size(self) -> u64 { =20 /// IMEM data register. Reading/writing this register accesses IMEM at= the address /// specified by the corresponding IMEMC register. - pub(crate) NV_PFALCON_FALCON_IMEMD(u32)[4, stride =3D 16] @ PFalconBas= e + 0x00000184 { + pub(crate) NV_PFALCON_FALCON_IMEMD(u32)[4, stride =3D 16] @ 0x00000184= { 31:0 data; } =20 /// IMEM tag register. Used to set the tag for the current IMEM block. - pub(crate) NV_PFALCON_FALCON_IMEMT(u32)[4, stride =3D 16] @ PFalconBas= e + 0x00000188 { + pub(crate) NV_PFALCON_FALCON_IMEMT(u32)[4, stride =3D 16] @ 0x00000188= { 15:0 tag; } =20 /// DMEM access control register. Up to 8 ports are available for DMEM= access. - pub(crate) NV_PFALCON_FALCON_DMEMC(u32)[8, stride =3D 8] @ PFalconBase= + 0x000001c0 { + pub(crate) NV_PFALCON_FALCON_DMEMC(u32)[8, stride =3D 8] @ 0x000001c0 { /// Auto-increment on write. 24:24 aincw =3D> bool; /// DMEM block and word offset. @@ -463,29 +462,29 @@ pub(crate) fn usable_fb_size(self) -> u64 { =20 /// DMEM data register. Reading/writing this register accesses DMEM at= the address /// specified by the corresponding DMEMC register. - pub(crate) NV_PFALCON_FALCON_DMEMD(u32)[8, stride =3D 8] @ PFalconBase= + 0x000001c4 { + pub(crate) NV_PFALCON_FALCON_DMEMD(u32)[8, stride =3D 8] @ 0x000001c4 { 31:0 data; } =20 /// Actually known as `NV_PSEC_FALCON_ENGINE` and `NV_PGSP_FALCON_ENGI= NE` depending on the /// falcon instance. - pub(crate) NV_PFALCON_FALCON_ENGINE(u32) @ PFalconBase + 0x000003c0 { + pub(crate) NV_PFALCON_FALCON_ENGINE(u32) @ 0x000003c0 { 0:0 reset =3D> bool; } =20 - pub(crate) NV_PFALCON_FBIF_TRANSCFG(u32)[8] @ PFalconBase + 0x00000600= { + pub(crate) NV_PFALCON_FBIF_TRANSCFG(u32)[8] @ 0x00000600 { 2:2 mem_type =3D> FalconFbifMemType; 1:0 target ?=3D> FalconFbifTarget; } =20 - pub(crate) NV_PFALCON_FBIF_CTL(u32) @ PFalconBase + 0x00000624 { + pub(crate) NV_PFALCON_FBIF_CTL(u32) @ 0x00000624 { 7:7 allow_phys_no_ctx =3D> bool; } =20 // Falcon EMEM PIO registers (used by FSP on Hopper/Blackwell). // These provide the falcon external memory communication interface. =20 - pub(crate) NV_PFALCON_FALCON_EMEMC(u32) @ PFalconBase + 0x00000ac0 { + pub(crate) NV_PFALCON_FALCON_EMEMC(u32) @ 0x00000ac0 { /// EMEM byte offset (4-byte aligned) within the block. 7:2 offs; /// EMEM block to access. @@ -496,7 +495,7 @@ pub(crate) fn usable_fb_size(self) -> u64 { 25:25 aincr =3D> bool; } =20 - pub(crate) NV_PFALCON_FALCON_EMEMD(u32) @ PFalconBase + 0x00000ac4 { + pub(crate) NV_PFALCON_FALCON_EMEMD(u32) @ 0x00000ac4 { 31:0 data =3D> u32; } } @@ -523,12 +522,12 @@ pub(crate) fn with_falcon_mem(self, mem: FalconMem) -= > Self { impl NV_PFALCON_FALCON_ENGINE { /// Resets the falcon pub(crate) fn reset_engine(bar: Bar0<'_>) { - bar.update(Self::of::(), |r| r.with_reset(true)); + E::pfalcon(bar).update(NV_PFALCON_FALCON_ENGINE, |r| r.with_reset(= true)); =20 // TIMEOUT: falcon engine should not take more than 10us to reset. time::delay::fsleep(time::Delta::from_micros(10)); =20 - bar.update(Self::of::(), |r| r.with_reset(false)); + E::pfalcon(bar).update(NV_PFALCON_FALCON_ENGINE, |r| r.with_reset(= false)); } } =20 @@ -542,23 +541,23 @@ pub(crate) fn mem_scrubbing_done(self) -> bool { /* PFALCON2 */ =20 register! { - base: NovaRegisters; + base: PFalcon2Registers; =20 - pub(crate) NV_PFALCON2_FALCON_MOD_SEL(u32) @ PFalcon2Base + 0x00000180= { + pub(crate) NV_PFALCON2_FALCON_MOD_SEL(u32) @ 0x00000180 { 7:0 algo ?=3D> FalconModSelAlgo; } =20 - pub(crate) NV_PFALCON2_FALCON_BROM_CURR_UCODE_ID(u32) @ PFalcon2Base += 0x00000198 { + pub(crate) NV_PFALCON2_FALCON_BROM_CURR_UCODE_ID(u32) @ 0x00000198 { 7:0 ucode_id =3D> u8; } =20 - pub(crate) NV_PFALCON2_FALCON_BROM_ENGIDMASK(u32) @ PFalcon2Base + 0x0= 000019c { + pub(crate) NV_PFALCON2_FALCON_BROM_ENGIDMASK(u32) @ 0x0000019c { 31:0 value =3D> u32; } =20 /// OpenRM defines this as a register array, but doesn't specify its s= ize and only uses its /// first element. Be conservative until we know the actual size or ne= ed to use more registers. - pub(crate) NV_PFALCON2_FALCON_BROM_PARAADDR(u32)[1] @ PFalcon2Base + 0= x00000210 { + pub(crate) NV_PFALCON2_FALCON_BROM_PARAADDR(u32)[1] @ 0x00000210 { 31:0 value =3D> u32; } } @@ -566,23 +565,23 @@ pub(crate) fn mem_scrubbing_done(self) -> bool { // PRISCV =20 register! { - base: NovaRegisters; + base: PFalcon2Registers; =20 /// RISC-V status register for debug (Turing and GA100 only). /// Reflects current RISC-V core status. - pub(crate) NV_PRISCV_RISCV_CORE_SWITCH_RISCV_STATUS(u32) @ PFalcon2Bas= e + 0x00000240 { + pub(crate) NV_PRISCV_RISCV_CORE_SWITCH_RISCV_STATUS(u32) @ 0x00000240 { /// RISC-V core active/inactive status. 0:0 active_stat =3D> bool; } =20 /// GA102 and later. - pub(crate) NV_PRISCV_RISCV_CPUCTL(u32) @ PFalcon2Base + 0x00000388 { + pub(crate) NV_PRISCV_RISCV_CPUCTL(u32) @ 0x00000388 { 7:7 active_stat =3D> bool; 0:0 halted =3D> bool; } =20 /// GA102 and later. - pub(crate) NV_PRISCV_RISCV_BCR_CTRL(u32) @ PFalcon2Base + 0x00000668 { + pub(crate) NV_PRISCV_RISCV_BCR_CTRL(u32) @ 0x00000668 { 8:8 br_fetch =3D> bool; 4:4 core_select =3D> PeregrineCoreSelect; 0:0 valid =3D> bool; --=20 2.54.0 From nobody Sat Jul 25 00:16:38 2026 Received: from LO3P265CU004.outbound.protection.outlook.com (mail-uksouthazon11020086.outbound.protection.outlook.com [52.101.196.86]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6411539CCFB; Tue, 21 Jul 2026 16:54:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.196.86 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652892; cv=fail; b=AXaYYexmwnp8FqaUifAemxWghw7goheO659mu6NQWGH4lQRj79wa8pmik3OKSq65oEy8VY+gh+lRriV7Np9Wp1UjVzRy82ZG2P2hsFw9VPYQF2RuLZsY6+g8MIxfvmSieq9C4IjoqBoa0gP2unMzTAw4pv5+MKHqA0Ngmd9vzyM= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652892; c=relaxed/simple; bh=v1AhLEytp+ubGM9er1SfcTppOcOxQOUG4YK7S3jTrxY=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=PJ4km7gAEoapc3/DHSGOY7OPz7foX7Qshu3jpak6CdHOtc4aa4ubuye0B4BTmJHjUbnfKRlV78Z7heEFxr7us3sLy/XrZ9kOBl7qQzSIP4awv5BoAtFULwqTBxzJlsSmAANPWUcnyBio17GpFFcp/MWBMQm1xm5QrWDRHwdAe2I= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net; spf=pass smtp.mailfrom=garyguo.net; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b=QxPfcSmJ; arc=fail smtp.client-ip=52.101.196.86 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=garyguo.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b="QxPfcSmJ" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=skukv3Djd6nNosB3bRXfr5V9G/J8+Ux6Mp0woeURF+GVTbZKtztMtlKC2nOrHmQ+gked6tetGuK8zqFU13cYv/Mf5gEQUMRLMpjZFZWt2iK3KwFjmewVbtbAvsszmj+MSn+4FA9dKFeVPLpVgG5Q4oBdriWpKGq4ME1bPXaaHAbxAwoR62g/0uATeW/NDZR4g+iXmb2a/zZq39mad1O+XuuWVNHEKDABlrBU7YfYZt+NeA89xIASMglGn2D6y8wxX7NkZ5q4nxtTK7Y4QTm82Qa5rDggT/aUKF4XOZd9cv1GM2y+8pXPny7vtGWbBiYnfNTd3pv4A5esXmA1qKO++w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=9U1O/G0PdIjgKwC9lMycnNTEDGZPORy/i+sUq9XpXAQ=; b=IcmCihfnFs8rz9JwP4A32klatzKXwXWYJTN2F8Z7BIxvFpKZ8hDgtI16ZURFEAG/fmZNgU/2BLgx/v3OsD3k6V0P2BOr9JCBOgjUUvxYGA9wncbbTH8ID77oh85ehydWkiUjMZtFEPSpgKSHGoj4uZsy0G8MK6ijS7wj9/IZSL8MPuT3E2YzCALiANBf9xT6HPE2Xnia/Rf1poUKdBxMmNzZxJi9R8x5+Fp79sR/InDLR6NAAW6bgOr5jeEclenBEFvmPmQdBrh684PthxnvLZjyjQAmmQrs98ztR3lBTIaPODbS5/L/kCYYCrbT7US/ZXKkZF9jcQrc1LbPqauBtg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=garyguo.net; dmarc=pass action=none header.from=garyguo.net; dkim=pass header.d=garyguo.net; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=garyguo.net; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=9U1O/G0PdIjgKwC9lMycnNTEDGZPORy/i+sUq9XpXAQ=; b=QxPfcSmJrLzstNVJ29bGDNqIMvUJ1f38BEI6tIoixvYn2V+0qavAWNQSSdGt0CfiQl0RzKDMvgeoPP3PeoI/B470JDAmPI7vMIpYox0HLaNkPvAnhBB8TMGUL6wXed60J5n3scyiAMQDxbGlsaNmUMDqYVrX6FFIMayp19x1jQ8= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=garyguo.net; Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) by LO8P265MB7878.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:3ae::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Tue, 21 Jul 2026 16:54:38 +0000 Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986]) by LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986%4]) with mapi id 15.21.0223.017; Tue, 21 Jul 2026 16:54:37 +0000 From: Gary Guo Date: Tue, 21 Jul 2026 17:54:33 +0100 Subject: [PATCH 09/10] gpu: nova-core: convert hshub0 from relative register to projection Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-typed_register-v1-9-452d72b60262@garyguo.net> References: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> In-Reply-To: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> To: Danilo Krummrich , Alice Ryhl , Daniel Almeida , Miguel Ojeda , Boqun Feng , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , David Airlie , Simona Vetter , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= Cc: driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, linux-pci@vger.kernel.org, Gary Guo X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784652872; l=5363; i=gary@garyguo.net; s=20221204; h=from:subject:message-id; bh=v1AhLEytp+ubGM9er1SfcTppOcOxQOUG4YK7S3jTrxY=; b=ID3jt47eVs7jdqWoN2OOu+OOrmCzvsaCkStotLa64wc55VDv1532zGICa44Layqayp2pGYXWF bSgrc3qliorAdQmJy82eTujUJkIbevjC0ofyG5cpVMw+MmR9REOrblv X-Developer-Key: i=gary@garyguo.net; a=ed25519; pk=vB3uIX95SM4eVrIqo1DWNWKDKD2xzB+yLLLr0yOPYMo= X-ClientProxiedBy: LO4P123CA0143.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:193::22) To LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LOVP265MB8871:EE_|LO8P265MB7878:EE_ X-MS-Office365-Filtering-Correlation-Id: f141ebb4-b23a-49c0-67f3-08dee748c00a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|7416014|10070799003|1800799024|366016|56012099006|10067099003|6133799003|22082099003|18002099003|921020; X-Microsoft-Antispam-Message-Info: +ZIPC95uqLTYltm/6l1eXLxyFH7kpGA53q6euFwuAsGWEt4DE9CbgCZoh3SfhHqjRNmLlWZLY9k/JBtpS/JEyFGh9pJiGKas4QY/5L51UdcS6kqW+abMbFXrh26za1NPqo1aP2Xnx3aILrkyhvZ2XVZybI4DotExcutWZjRe9B7ZJQNfUHAfyIuPH/NSphZ345zQ4Ge4WfowY+Pu5qSgmgmHB0Dwc5OOBfkjDi0jYRUCpXy/9jTK/hcxw79ePmSRnRXBKarQiulW+12ddWuqdAfd1KVL7ysRb5fj8YdXPl9Lu7cYYAqPve6VvuR/rH3D5O7VBBpJvO0/YRN9VQiaFpj1E9rb3AZEC8p6Uh3T0SdhxRMuL3Ed/Q87OZ59wKbUnjoFh1DJtBWlD4VH7HKa3sYq47AmAI9TWMe9pCT8wk2pVRzSePD0SYqv4UNWj9gXqSm5KNIJoDMtxkrNZLx2eneZCAyu93ukOsmbbiJnGLILc5lo2nTbg/8DVApN6KO7Z9UzXPsPPvaSKcj3/GbzCu6lptoy6NbDYQspr3J6BeI8q6L3gtfPAMn0cl4JxTcvLkVsoPhZ3HEU6bQFNUh46/rYtxEBzM5t6GwRBDHJ3Xlt3HThHWzBl8NkuDwJU2dsINi83LmdHosBaCgHtSm2GxHWjsDSPNTlaFA7eTt9dN/xJ8Ce5FCxZW0oQXcJjCW9RGZY6LcDzU4lkt3G/Fuuvg== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(376014)(7416014)(10070799003)(1800799024)(366016)(56012099006)(10067099003)(6133799003)(22082099003)(18002099003)(921020);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?dmNvVk9XU2l6ZktONVl3NW8yYmxLRDVIUGltaHdLcFMyZWtZdk91NlE0Wng0?= =?utf-8?B?NHZjOHFlZC9hZnIvd0Z4RmNyUE1vYjJRS2poVWdvaUQyOUw3R3BqejFvNG9x?= =?utf-8?B?c25ZZG5PWFVUWUltd0lMMHNvRlQ4Z29uVXlBK1g4WjdIR1dEVFlsV3VmQXkr?= =?utf-8?B?cU0xRWJNQ3BiS2NUWGg5ZVdSMnJEZHdMb3U2U1Q2NHA4ZjRVMDlXamtIZ0d5?= =?utf-8?B?eEoycVhsbWRKUnIrZ0owQUJsdlA1MlR2VkcwU21NSXN2T1ZtMnRaMXNYREhu?= =?utf-8?B?T212cWpuVlJ5TkU5cE1DRlNOSmNLSXF5U0kxU1lKelNPNGh5eUlVVDZsdmZ3?= =?utf-8?B?NE9LMHJuS2ZURlNDRmRDTDk0WGtLRGQ0VTI1RmF4bllyNVhEczBEb25QVVlP?= =?utf-8?B?TE5Vb1BJVkxSanRtMTRXQW1xMXhyNTdRejBWajlqTEpKbWUweGtLb2g3Q3kx?= =?utf-8?B?djAxZkFuR05BNGFiNkd6K0xpMzJNcmJ0YmpLMC9KcUx3dzloZHUwTi96Ty9x?= =?utf-8?B?UWFEUlJMcDhodDBYUWtJMXJtL05EYVhNRVNKZGdpWHZ3RG1lYlJoZDViamZx?= =?utf-8?B?aG4zemhzUnMyT0lDM0lDWVltdTlkVngyVWZkcnNkeFg4U0lZckxjQ2N6THVo?= =?utf-8?B?bmJyVkY2SHVGcE45MGd2dFo3Y3ZqSUJCN0JEVllXeWIydnE1Z2ljaUl0aUFC?= =?utf-8?B?R0NzQW1JcHU0em1QYUFtRDlUbnFleVViWi9RMjIrcGRPSWw2M0x6QnZsd1U1?= =?utf-8?B?WkRLcGp2RVlhaXcrTXlGTlh4d0RVZTBzQnBxWnExSW1oMDBqdEpOZlpUVW01?= =?utf-8?B?V09FL0VnblhzREZydHZYNE8vcEc5RHZ0cnFwZHVLVm5aOExWYkI5Q2puUXZ6?= =?utf-8?B?TXpLY0ZQRms5TTZrL05PdS9XM09MeU5jazVYRDJoc2VteEovczBFS3BSNWxk?= =?utf-8?B?d2RJWG43eXZ6ZGNidC9qR1pVbDJhRkZWbTBCWXJtRzUra1dpZkdHcE45dnFP?= =?utf-8?B?Um5EdHZtanhNUkxweVRXbVFiMHpKY3A2NjJDb1hnR21PenpMWnpiRmE5R1Ni?= =?utf-8?B?VVpDNXh1WU1xZC8zaHVhbHBFcEVsTWlvZFB2dWxHZE1YbXoyYjlGOC9nQ0FS?= =?utf-8?B?b2hWRUNzdHY2ZTlPeDdmbHdObk5RNit4elViUUQwOXN2QjlmcmpPeDFXeFhV?= =?utf-8?B?MXVPMkZkSUd2QVB1eDZlcU41ZlcxNGRMc3J6RHdHZmVobk84dGhhVTRvQ2Jr?= =?utf-8?B?dHhDQTFVbVljMEZ6TFN5R0tVejBGNEJvekpkM21NWmh2YmJ4RFRObFNBbEI3?= =?utf-8?B?em5Nd1c0azJXWkVZcmExWUFyYno1cSswOHB2eE9EdGlCS2Q5WHBLRmpyeVFn?= =?utf-8?B?dm8zUnZoWVhMSWFRNURraXBkU09wcEg1WS95eVlKZXJQd080M2JKTWVNSTMx?= =?utf-8?B?b2RjNEZpUE9kMUJjVER5cXlMK0hPN3VoS3NRVk85bGFhQlVDQXpTNmxqY2Rz?= =?utf-8?B?VjZ2WXdCZy9xRDFTWnRZODQ0TkdueGZGbW8xYm9TRTRjbWttYzQ3NjhybDZp?= =?utf-8?B?d2NFLzQrL1QvTElBWjVkRnNINThTOEVORmVFeTdnUkVOUVRpZEduQmRZQWdR?= =?utf-8?B?eFdGRWVQOVEzR3R6eFVsQnBmcjg5bFV6SmpZUzJIdE0xWkgwdE53ZnNXRnFX?= =?utf-8?B?eXh3SndDQ2IrRW5VSFpnR2wybFdicEtVWTJkaGlVdjhzY0ovT3AwSEVXcU9a?= =?utf-8?B?djdvRjJyZkZITDVxV1IycWo1MWs0OUYwQldFcmdMQ25UZWdnNzVYYnRsV1Y3?= =?utf-8?B?dXhBV2JkOE13NzA1bmNQTi9hZElLY0ZtRWpPRTg5cVVnclBJS1pYR1Q3Yjcv?= =?utf-8?B?QkZXd3VGMWUyS2ZIRUkzeXgyNUV5RVJQWWg5T1d1N3kzMHA2dDR1dXBiVDEx?= =?utf-8?B?VHFOdUNUeFhoUnZjMFMrUE9IM2ZUSkh5YlZaQzQ4QURURklaeDR5ZGhrQ0pl?= =?utf-8?B?MXA0QWk4cVVNaGhFbWFzZGRkdDNJTVY4dUJJRjBFQklhaWpvMEJ4MHY1R0tx?= =?utf-8?B?akhYZlRGR1JhMU8zWTZFZVVhZ3U0MDU5TVFERkdleFFqdzF5YmxGQmhvL1Er?= =?utf-8?B?U2ZyNDlNSzFoQjQyMitFSVNQN1JqNnVWdFNOeG96OTlweUt3V29iSWEvOEhn?= =?utf-8?B?VGh6Zlg1NWFJSzEzTU5qWjNyYlJCR21HRlZvdjRHTG5jOG5PR2pGUis0QXhi?= =?utf-8?B?Q0FPS2g4dnBlUGMxUkg5N21vZTRuOStCK3VyalJ1OWZlRi8vbk14ZXV5ckoz?= =?utf-8?B?MDJCSWVTMU5xTjRIbXRna2JDTEZsR0dtKzhwV2s0dlJkVVhUK3ZKZz09?= X-OriginatorOrg: garyguo.net X-MS-Exchange-CrossTenant-Network-Message-Id: f141ebb4-b23a-49c0-67f3-08dee748c00a X-MS-Exchange-CrossTenant-AuthSource: LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jul 2026 16:54:37.9343 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bbc898ad-b10f-4e10-8552-d9377b823d45 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: d1+PqdJf/cGddBCZqJTifG1WgMtS6qbA4v8Ho1NfU/UFDLqBjx644BgleN0ghmTLKQlD9FomVFgYgZB3/zqnig== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LO8P265MB7878 Similar to the PFALCON and PFALCON2 conversion, the hshub0 relative access can also be achieved cleanly with projection and a new base. Signed-off-by: Gary Guo --- drivers/gpu/nova-core/fb/hal/gb100.rs | 51 ++++++++++++++++++-------------= ---- drivers/gpu/nova-core/regs.rs | 19 ++++++++----- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/nova-core/fb/hal/gb100.rs b/drivers/gpu/nova-core/= fb/hal/gb100.rs index 6e0eba101ca1..ec910e0a044b 100644 --- a/drivers/gpu/nova-core/fb/hal/gb100.rs +++ b/drivers/gpu/nova-core/fb/hal/gb100.rs @@ -5,11 +5,9 @@ =20 use kernel::{ io::{ - register::{ - RegisterBase, - WithBase, // - }, - Io, // + Io, + Mmio, + Region, // }, num::Bounded, prelude::*, @@ -29,17 +27,24 @@ =20 struct Gb100; =20 -impl RegisterBase for Gb100 { - const BASE: usize =3D 0x0087_0000; +impl Gb100 { + #[inline] + fn hshub0(self, bar: Bar0<'_>) -> Mmio<'_, regs::Hshub0Registers> { + Region::subregion::<0x0087_0000, SZ_4K, _>(bar).cast() + } } =20 fn read_sysmem_flush_page_gb100(bar: Bar0<'_>) -> u64 { let lo =3D u64::from( - bar.read(regs::NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO::of::= ()) + Gb100 + .hshub0(bar) + .read(regs::NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO) .adr(), ); let hi =3D u64::from( - bar.read(regs::NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI::of::= ()) + Gb100 + .hshub0(bar) + .read(regs::NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI) .adr(), ); =20 @@ -58,24 +63,20 @@ fn write_sysmem_flush_page_gb100(bar: Bar0<'_>, addr: B= ounded) { // Write HI first. The hardware will trigger the flush on the LO write. =20 // Primary HSHUB pair. - bar.write( - regs::NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI::of::(), - regs::NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI::zeroed().with_adr(ad= dr_hi), - ); - bar.write( - regs::NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO::of::(), - regs::NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO::zeroed().with_adr(ad= dr_lo), - ); + Gb100 + .hshub0(bar) + .write_reg(regs::NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI::zeroed().= with_adr(addr_hi)); + Gb100 + .hshub0(bar) + .write_reg(regs::NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO::zeroed().= with_adr(addr_lo)); =20 // EG (egress) pair -- must match the primary pair. - bar.write( - regs::NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI::of::(), - regs::NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI::zeroed().with_adr= (addr_hi), - ); - bar.write( - regs::NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO::of::(), - regs::NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO::zeroed().with_adr= (addr_lo), - ); + Gb100 + .hshub0(bar) + .write_reg(regs::NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI::zeroed= ().with_adr(addr_hi)); + Gb100 + .hshub0(bar) + .write_reg(regs::NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO::zeroed= ().with_adr(addr_lo)); } =20 pub(super) const fn pmu_reserved_size_gb100() -> u32 { diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs index 7f7cb84b21e8..6bc8601f2176 100644 --- a/drivers/gpu/nova-core/regs.rs +++ b/drivers/gpu/nova-core/regs.rs @@ -7,7 +7,10 @@ Io, // }, prelude::*, - sizes::SizeConstants, + sizes::{ + SizeConstants, + SZ_4K, // + }, time, // }; =20 @@ -156,28 +159,30 @@ fn fmt(&self, f: &mut kernel::fmt::Formatter<'_>) -> = kernel::fmt::Result { /// Base of the GB10x HSHUB0 register window (`NV_HSHUB0_PRIV_BASE` in Ope= n RM). /// /// The base is provided by the GB10x framebuffer HAL. -pub(crate) struct Hshub0Base(()); +#[repr(align(4))] +#[derive(FromBytes, IntoBytes)] +pub(crate) struct Hshub0Registers([u8; SZ_4K]); =20 register! { - base: NovaRegisters; + base: Hshub0Registers; =20 // GB10x sysmem flush registers, relative to the HSHUB0 base. GB10x ro= utes sysmembar // through a primary and an EG (egress) pair that must both be program= med to the same // address. Hardware ignores bits 7:0 of each LO register. The boot pa= th uses a fixed // HSHUB0 base, so the multiple runtime-discovered HSHUB bases are not= needed here. - pub(crate) NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ Hshub0Base + = 0x00000e50 { + pub(crate) NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ 0x00000e50 { 31:0 adr =3D> u32; } =20 - pub(crate) NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ Hshub0Base + = 0x00000e54 { + pub(crate) NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ 0x00000e54 { 19:0 adr; } =20 - pub(crate) NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ Hshub0Base= + 0x000006c0 { + pub(crate) NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO(u32) @ 0x000006c0= { 31:0 adr =3D> u32; } =20 - pub(crate) NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ Hshub0Base= + 0x000006c4 { + pub(crate) NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI(u32) @ 0x000006c4= { 19:0 adr; } } --=20 2.54.0 From nobody Sat Jul 25 00:16:38 2026 Received: from LO3P265CU004.outbound.protection.outlook.com (mail-uksouthazon11020086.outbound.protection.outlook.com [52.101.196.86]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 708B4381AF1; Tue, 21 Jul 2026 16:54:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.196.86 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652895; cv=fail; b=Cm7NRVbTKscO5+ghnQohX6aa8EuL+hSKCODc19MHT2GWM5Rvwl5ZtkuphIjXcUTjOHGZk5am07xBYEOQxgqsNtpe0H1DCjuJGvlBukgJKrdYR5fMyHXJGWO68/hCnFJ6TrWgqmvdfAM9sH9+XGFe4xI3QwR77Nq4qoWq8YKAs+o= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784652895; c=relaxed/simple; bh=0lk1tT21wk00ME8X9EtuM9WZ/LhWLpfXQthdWTrO4H0=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=tpeuWfB7rnH/4NTLfiVSoMhRaDU+/p58a+lEyvLA0koEKi/o/tJ66+hNFdO4Ky0hrcJbXB4J5MTwrV/BZxnirJBQP57AoFyRj4qw9cFdYWp1Bu5ynz63+gg/rvAwLZYnZ5HLfhKQiys4ZHbogTXVwCw8CCbXiHJZcTAKUvK6Yvw= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net; spf=pass smtp.mailfrom=garyguo.net; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b=mNgBNBtd; arc=fail smtp.client-ip=52.101.196.86 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=garyguo.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=garyguo.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net header.b="mNgBNBtd" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=OjHOxo2LN/iNtnlYePW6z2mTp4kcanA3/tkIdNmhO56a2GmuHLZy7elsD+GYgujub8kZD9E1+N99ylf87uojBQ0oSs03Cb2dCcX5xtxSHsyMPqovXNQN5IHUEfsnBArwqtOtw6FFiP6US7vfmnMHl6x5WFQ0/bSDBNLZAXIrT69og+ZzkjOeh735thElpz+XFAKvR2p+QbL3Bb8yGPrDNGuX8OEgDXXjuJ5IBJCMuN3A9ADTsPwZC1jy1AVEm83uPqYYAN3pfXqHUFSE7S9Qd5yBhBo68q94gb3JdOMfPG7bVhTQRVQJ3RYw1KVqRzkBasH6ZEQ9OVqnqypS2IRhHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=0Isb2qRjG2IOYlLfoblXZPhuZ8hatUUlVZuaUx1uueU=; b=p6PJ86UOCWTF6RwL6xjpqzLhApvaTmux17JNK8xh2xrJdI1ULEQo3fleyxD5vQPn3BopWip55D9fG57GJQpFOYPMF8j9bBZ0vVgHhj1dwt6aLpZOYmi9ETeV8vehCk0bGk+MONMTzdA8mHar9tOq38jYZ0YJg1NuzdaPh8zFxftknmgusuPljNs5jqqQrHQvEYI63xDUqs6TloY2NX/6ILQwemR9rRGQKMDWH4lmzniqC5dRIphIOfH2YzlvV980cQf5XT5sFAQozQCsTs70vAGXR8FIUHHhzUePHC7WTMkeUmwB7zu0ZxTxCDycSt54ZfzfhYkn7lYYqypjurdCLw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=garyguo.net; dmarc=pass action=none header.from=garyguo.net; dkim=pass header.d=garyguo.net; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=garyguo.net; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=0Isb2qRjG2IOYlLfoblXZPhuZ8hatUUlVZuaUx1uueU=; b=mNgBNBtdcoEbEAv4GQaz2Zq2GkdXlMAuN3xcY2sKmjoiKcECAcxFzLPmx5ZuN5Yb2UkH9bOcI/lXA1YP8aoZ8Th3fkZ14we76AolKma0m/5mriL5f5etvptIZaWDRRanngyWirfHhf0ky8a4uD2LZdibO0Y4mJvX5fhQePQEBpM= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=garyguo.net; Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) by LO8P265MB7878.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:3ae::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Tue, 21 Jul 2026 16:54:38 +0000 Received: from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986]) by LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM ([fe80::1c3:ceba:21b4:9986%4]) with mapi id 15.21.0223.017; Tue, 21 Jul 2026 16:54:38 +0000 From: Gary Guo Date: Tue, 21 Jul 2026 17:54:34 +0100 Subject: [PATCH 10/10] rust: io: register: remove relative registers Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-typed_register-v1-10-452d72b60262@garyguo.net> References: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> In-Reply-To: <20260721-typed_register-v1-0-452d72b60262@garyguo.net> To: Danilo Krummrich , Alice Ryhl , Daniel Almeida , Miguel Ojeda , Boqun Feng , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , David Airlie , Simona Vetter , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= Cc: driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, linux-pci@vger.kernel.org, Gary Guo X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784652872; l=20299; i=gary@garyguo.net; s=20221204; h=from:subject:message-id; bh=0lk1tT21wk00ME8X9EtuM9WZ/LhWLpfXQthdWTrO4H0=; b=HqZLBa1CLQMjE9VVupYEngU69n60gQGQNVytkOXX3GgTJoEzK1eKnP7q5jhUPOJyNB3WCL7jT yMCAvg0A6XTCObZ+ucKPUP6xY5yaCWkkm1PLd9WQelTvc3/ffpm1+KW X-Developer-Key: i=gary@garyguo.net; a=ed25519; pk=vB3uIX95SM4eVrIqo1DWNWKDKD2xzB+yLLLr0yOPYMo= X-ClientProxiedBy: LO4P123CA0143.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:193::22) To LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LOVP265MB8871:EE_|LO8P265MB7878:EE_ X-MS-Office365-Filtering-Correlation-Id: 4cc05bfd-b81c-4de9-1e00-08dee748c059 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|376014|7416014|10070799003|1800799024|366016|56012099006|10067099003|22082099003|18002099003|921020; X-Microsoft-Antispam-Message-Info: jnnjPr8GgexPdYnLU2b4jm19PApwXZs1nqB8yUHd4F6mocf4sJ6vITAOz8qcYDt35AfB+nvGQNG8tIkxmLJGQqtUW9vRLmhUPiifUUXh8FZVP1oPJtxGSNh02uQwM8UdoH7Tbx7AIRiBC/uOAWOJA+57DnW69Mjht3WE9PYerufio59+xkskdtQsjPMcyrX8Ekfi4/KiDy3v7XJq7zZDqbn77w++zrL9o0qBOcZnglPmrQrJyL0nRkWaXJG7yEtCrudLiKiL4inlpDLK1pTEBhG5hKaTulG7zEK1vKMH+hDSCFMW+257k1KIF1RA7X3J2+eY6goTHh4NkS6ey4uqMsmb3XigkM7nQ5qpuCXlA5BDzCtxt+Vxe5idwbZP4JdC+it7U3Nh9/fFfDCAup3DwG/BmS/jQ0H/5JbbSt+oRIKCxp6ctBCkqXWXyXRI+Gl6P7BsEOwdm6x5zKkFceTwMYZubQwY1Uate7tE1Y4G13WJ8ma3mMakYfE0gxDglht5N6KS/R8VcUgXpXkJQemfcNOXEDisDpRoxrBJ5SCBvr82yuYc1C+ievzSw1i3m28OmdzZ7NPUU2m2IRWN4ewkMnKcT2qhb14zN0KfPDelZ3Q6lK2XQcIWahe9QGx7X3LVmvez7EDuoG7yyfU8d0ShTx5p0IL+eZEHFHks7sVbTB7Z1yqfJ40rfqlDPDwCGbMkTrENxICZrZQFKvt8VjbuwQ== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(376014)(7416014)(10070799003)(1800799024)(366016)(56012099006)(10067099003)(22082099003)(18002099003)(921020);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?Sk9DWWgvNmVDekdEbWRrNGFPQlFESXNra0NYSUpoVE5ZODMyRmorSWRNWjc3?= =?utf-8?B?dzRBa1I2cjRoeVBhYUdBTjA3VzZaSlBzRzV6YlpXYS9SUlJxb3diMjY0MUdO?= =?utf-8?B?NUkzR3pSVXc5Y0dsSDBqM0FKU0k3bnpiOSthSk5IdXRzcGxQTHk3bzhDamxR?= =?utf-8?B?NFp2VndqYWtYdVZreXNOTjkxR3ZSZzJvQzFCclNOZnVuSFR1YmdENUNhc3pp?= =?utf-8?B?UlN0YXV2cEhXbldiZ0tFcTZ0VlMzUUpLajVIZGJqc3oxak9hTHc3NE94Nktj?= =?utf-8?B?NXFKdGdUYythL2lIN0s4LzgwTWc2NTV4eWN6c2VQVHk0L2xQdWxwejNhWmor?= =?utf-8?B?OElBaW9KQlRCUnh2bHVkbnQ0OTFvQzBWYmtuZmt1aVByUnFHT0M3U3FaMzht?= =?utf-8?B?eXpPL05UNUYwcEtRZk15RlArVU5ac3E2TUI5ZVc0aGwxL3F5ellHSEZGeEw0?= =?utf-8?B?WGlQei9iSVVnNXF3YUdZa3N1T01MSEdiZ1NkTm0vekMvS2szQzJrVSttU0dv?= =?utf-8?B?a3VSNzd5SUlvanFFWGd1UWQvWm9lZDFpNVFDQVRNaUtUZ2poRWxUaDFTNFAx?= =?utf-8?B?eDZuUWhJT0hvbi95U3pXMUVJR2pQcWJLVzJTNnh2Z3ppRXRPbnBaNTBPNGho?= =?utf-8?B?dFhBclpMNGZtbm9QcWxJU0lkOUtzQXVZU2JuRUJIUjV2VXp6dGVObmsrQTZB?= =?utf-8?B?dDBYMUpwUFVnejhYWkFiRWhmR2FEN21UbFVkUTg5T0NWbnBFRko4RkJvVTVU?= =?utf-8?B?aHozRGdRTnEza24vU0tlSHdyYVlFSnEySU1sQmpzK2ZSeHNldnY2L3l1dmZj?= =?utf-8?B?alZzQ2dPL2RqYVBLaWhvaUZSUHBMUVR5TVNTQlRPSGNpVlkwSUNHR0hmSEU2?= =?utf-8?B?Vlk2djJUU3NqdkE4L1NsbW1ReFZjb1hjU21hai9yNTBxU09QN3U5dVd3VlRO?= =?utf-8?B?K2FaNWthYnprMy9WSUVZOEJYN2dWaGhHWDVDQmJmWm9mVVVua2FMQlErVUhw?= =?utf-8?B?VnZ2Z0p5dHJSR1lsV255cnY4U1F5OCs3NVQ5cWIvblRIWndLR21FMWo0Zmth?= =?utf-8?B?SkV3c3VPS1pUNGhwOE1oTG5ONEUrNlNld3RLY1dnQ1NYa3VSTE93UnYvZXNE?= =?utf-8?B?MGdhekhraFM0UjhhK3NSd3E5bjZuNTVEaHhweUhPQ3M5NHFxNHlSSk0yQTVG?= =?utf-8?B?bUhaNWlDbml4K2JBNm1VNERWWCtHYnJNa2FaMDNwZ1pFWVlvK1gyZjEzN0xy?= =?utf-8?B?KzZueXFhaFNVK21rZEtZdU1XNnhJdXViWDRXWi9uUWVtY1c3QkdWaHVnTHhS?= =?utf-8?B?UXREK0YvVTZkelc3TDNCL1J3NkRTSS8wZjAyWEs5Zm4veUxLS1FnMDJwemQ4?= =?utf-8?B?U1lJUTZWbXBBSzNhM2RRNmJSWFphY0RNaHM5VzI1ZFFXZzA5MzdqYjdwSE4w?= =?utf-8?B?TUIyTEEvNkRkUlNDTmFUdjdCNTc1eVJwd0J4TjhNOVdlVlhZcDBNdlVtOGhD?= =?utf-8?B?VnoxZ3RWY2cvRlVLOGl6ejdZUHJ3dUtTSzB4M2NObEd3Q3diaUNIcFgwS0ls?= =?utf-8?B?anJrRERTQWlhRGdTYU1UUktTSEgyd1FEb3ExRlJ0L1ZxZEpKUkdsTWI0YXlB?= =?utf-8?B?ZUphbEl3SHFkYnZNVW1iRXZwUlFjSnNUdzNiQ1lVRHVGaHlWQUpQN3p1Tkln?= =?utf-8?B?ek5kWDFPakFuK3BIYU1DK1B5Nm1qcU9oMmJld2hzcmhrd1psVFNHQUVjRkZX?= =?utf-8?B?eDQwRlJvOFBFTlhTdUljeklOVGFqbTd1WTJpbUhIaHJGdUpMMHkxamdQc1Vz?= =?utf-8?B?Z2FQRUZLem5xRWluQ0FDbWZ2alNoT0haWnM4aWJkQmRPRkhKTUJNa0NoRVpl?= =?utf-8?B?QmRCN2E2dHk4c0QwckxqWFdvcGpBNmI3TFRSV2tUYzZHZjNNZmFKZWY4RlNs?= =?utf-8?B?SVRhb0dzSm13ZDJmb00rekEreE1yVUR5L2lVNzRISVZ2a1dmaDFHOXE4eE5u?= =?utf-8?B?MmN6c3NMZmZXZWpFcGRZalhQWWp4ZWtyZUZqdVFYNzZmZncxSzJNK0trdXpq?= =?utf-8?B?MDd6Ky9pK2I5T2xYU3d4ekxNU2xvUHl0aEtRYWdDSzNGOVJzN25LU1lJKzVO?= =?utf-8?B?YnpsdW1BOGx5b0RhTkp4RU8xRUR6Y1lHbE1majdMTzBDN3UzaU4zazBCdGNT?= =?utf-8?B?N2kxdDVIZmhYSTBhbFZkT0RHcHRBSzdvQm1qK1pWVFVVcGhKei9tYTBFbVVL?= =?utf-8?B?b0dJS3NBeTZYSkpSc0YxR2NhS3AxY1Z5ZHM4dnlKdkpjT1JnWDJMRFJ6WUd0?= =?utf-8?B?aXk4VHV6dzhyMG9JQkVkWnF1NjBBMDk1SENORFJXT3hpMkNzQW9sQT09?= X-OriginatorOrg: garyguo.net X-MS-Exchange-CrossTenant-Network-Message-Id: 4cc05bfd-b81c-4de9-1e00-08dee748c059 X-MS-Exchange-CrossTenant-AuthSource: LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jul 2026 16:54:38.4726 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bbc898ad-b10f-4e10-8552-d9377b823d45 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 91/vIx89ToUmh4TpI8fYLZcs7JOTjPEa89dfj/OaguYsrhjZdiY/HBGBCnyWMGCJQW1mqPF+w6DpW+HbcJ0i1g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LO8P265MB7878 Relative registers can be better served by projection to subregion instead of ad-hoc handling in register macro. Projection composes better (e.g. it natively allows relative registers of relative registers without needing additional support). Signed-off-by: Gary Guo --- rust/kernel/io/register.rs | 469 +----------------------------------------= ---- 1 file changed, 3 insertions(+), 466 deletions(-) diff --git a/rust/kernel/io/register.rs b/rust/kernel/io/register.rs index df47c28ba4f4..88ead1c1874f 100644 --- a/rust/kernel/io/register.rs +++ b/rust/kernel/io/register.rs @@ -191,78 +191,6 @@ fn offset(self) -> usize { } } =20 -/// Trait providing a base address to be added to the offset of a relative= register to obtain -/// its actual offset. -/// -/// The `T` generic argument is used to distinguish which base to use, in = case a type provides -/// several bases. It is given to the `register!` macro to restrict the us= e of the register to -/// implementors of this particular variant. -pub trait RegisterBase { - /// Base address to which register offsets are added. - const BASE: usize; -} - -/// Trait implemented by all registers that are relative to a base. -pub trait WithBase { - /// Family of bases applicable to this register. - type BaseFamily; - - /// Returns the absolute location of this type when using `B` as its b= ase. - #[inline(always)] - fn of>() -> RelativeRegisterLoc - where - Self: Register, - { - RelativeRegisterLoc::new() - } -} - -/// Trait implemented by relative registers. -pub trait RelativeRegister: Register + WithBase {} - -/// Location of a relative register. -/// -/// This can either be an immediately accessible regular [`RelativeRegiste= r`], or a -/// [`RelativeRegisterArray`] that needs one additional resolution through -/// [`RelativeRegisterLoc::at`]. -pub struct RelativeRegisterLoc(PhantomData, Pha= ntomData); - -impl RelativeRegisterLoc -where - T: Register + WithBase, - B: RegisterBase + ?Sized, -{ - /// Returns the location of a relative register or register array. - #[inline(always)] - // We do not implement `Default` so we can be const. - #[expect(clippy::new_without_default)] - pub const fn new() -> Self { - Self(PhantomData, PhantomData) - } - - // Returns the absolute offset of the relative register using base `B`. - // - // This is implemented as a private const method so it can be reused b= y the [`IoLoc`] - // implementations of both [`RelativeRegisterLoc`] and [`RelativeRegis= terArrayLoc`]. - #[inline] - const fn offset(self) -> usize { - B::BASE + T::OFFSET - } -} - -impl IoLoc for RelativeRegisterLoc<= T, B> -where - T: RelativeRegister, - B: RegisterBase + ?Sized, -{ - type IoType =3D T::Storage; - - #[inline(always)] - fn offset(self) -> usize { - RelativeRegisterLoc::offset(self) - } -} - /// Trait implemented by arrays of registers. pub trait RegisterArray: Register { /// Number of elements in the registers array. @@ -327,73 +255,6 @@ fn try_at(idx: usize) -> Option> } } =20 -/// Trait implemented by arrays of relative registers. -pub trait RelativeRegisterArray: RegisterArray + WithBase {} - -/// Location of a relative array register. -pub struct RelativeRegisterArrayLoc< - T: RelativeRegisterArray, - B: RegisterBase + ?Sized, ->(RelativeRegisterLoc, usize); - -impl RelativeRegisterArrayLoc -where - T: RelativeRegisterArray, - B: RegisterBase + ?Sized, -{ - /// Returns the location of register `T` from the base `B` at index `i= dx`, with build-time - /// validation. - #[inline(always)] - pub fn new(idx: usize) -> Self { - build_assert!(idx < T::SIZE); - - Self(RelativeRegisterLoc::new(), idx) - } - - /// Attempts to return the location of register `T` from the base `B` = at index `idx`, with - /// runtime validation. - #[inline(always)] - pub fn try_new(idx: usize) -> Option { - if idx < T::SIZE { - Some(Self(RelativeRegisterLoc::new(), idx)) - } else { - None - } - } -} - -/// Methods exclusive to [`RelativeRegisterLoc`]s created with a [`Relativ= eRegisterArray`]. -impl RelativeRegisterLoc -where - T: RelativeRegisterArray, - B: RegisterBase + ?Sized, -{ - /// Returns the location of the register at position `idx`, with build= -time validation. - #[inline(always)] - pub fn at(self, idx: usize) -> RelativeRegisterArrayLoc { - RelativeRegisterArrayLoc::new(idx) - } - - /// Returns the location of the register at position `idx`, with runti= me validation. - #[inline(always)] - pub fn try_at(self, idx: usize) -> Option> { - RelativeRegisterArrayLoc::try_new(idx) - } -} - -impl IoLoc for RelativeRegisterArra= yLoc -where - T: RelativeRegisterArray, - B: RegisterBase + ?Sized, -{ - type IoType =3D T::Storage; - - #[inline(always)] - fn offset(self) -> usize { - self.0.offset() + self.1 * T::STRIDE - } -} - /// Trait implemented by items that contain both a register value and the = absolute I/O location at /// which to write it. /// @@ -428,8 +289,7 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// This documentation focuses on how to declare registers. See the [modul= e-level /// documentation](mod@kernel::io::register) for examples of how to access= them. /// -/// There are 4 possible kinds of registers: fixed offset registers, relat= ive registers, arrays of -/// registers, and relative arrays of registers. +/// Registers can either be fixed offset registers or arrays of registers. /// /// ## Fixed offset registers /// @@ -514,122 +374,6 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// In this example, `SCRATCH_BOOT_STATUS` uses the same I/O address as `S= CRATCH`, while providing /// its own `completed` field. /// -/// ## Relative registers -/// -/// Relative registers can be instantiated several times at a relative off= set of a group of bases. -/// For instance, imagine the following I/O space: -/// -/// ```text -/// +-----------------------------+ -/// | ... | -/// | | -/// 0x100--->+------------CPU0-------------+ -/// | | -/// 0x110--->+-----------------------------+ -/// | CPU_CTL | -/// +-----------------------------+ -/// | ... | -/// | | -/// | | -/// 0x200--->+------------CPU1-------------+ -/// | | -/// 0x210--->+-----------------------------+ -/// | CPU_CTL | -/// +-----------------------------+ -/// | ... | -/// +-----------------------------+ -/// ``` -/// -/// `CPU0` and `CPU1` both have a `CPU_CTL` register that starts at offset= `0x10` of their I/O -/// space segment. Since both instances of `CPU_CTL` share the same layout= , we don't want to define -/// them twice and would prefer a way to select which one to use from a si= ngle definition. -/// -/// This can be done using the `Base + Offset` syntax when specifying the = register's address: -/// -/// ```ignore -/// register! { -/// ... -/// pub RELATIVE_REG(u32) @ Base + 0x80 { -/// ... -/// } -/// } -/// ``` -/// -/// This creates a register with an offset of `0x80` from a given base. -/// -/// `Base` is an arbitrary type (typically a ZST) to be used as a generic = parameter of the -/// [`RegisterBase`] trait to provide the base as a constant, i.e. each ty= pe providing a base for -/// this register needs to implement `RegisterBase`. -/// -/// The location of relative registers can be built using the [`WithBase::= of`] method to specify -/// its base. All relative registers implement [`WithBase`]. -/// -/// Here is the above layout translated into code: -/// -/// ```no_run -/// use kernel::{ -/// io::{ -/// register, -/// register::{ -/// RegisterBase, -/// WithBase, -/// }, -/// Io, -/// Region, -/// }, -/// }; -/// # use kernel::io::Mmio; -/// -/// // Type used to identify the base. -/// pub struct CpuCtlBase; -/// -/// // ZST describing `CPU0`. -/// struct Cpu0; -/// impl RegisterBase for Cpu0 { -/// const BASE: usize =3D 0x100; -/// } -/// -/// // ZST describing `CPU1`. -/// struct Cpu1; -/// impl RegisterBase for Cpu1 { -/// const BASE: usize =3D 0x200; -/// } -/// -/// // This makes `CPU_CTL` accessible from all implementors of `RegisterB= ase`. -/// register! { -/// base: Region<0x1000>; -/// -/// /// CPU core control. -/// pub CPU_CTL(u32) @ CpuCtlBase + 0x10 { -/// 0:0 start; -/// } -/// } -/// -/// # fn test(io: Mmio<'_, Region<0x1000>>) { -/// // Read the status of `Cpu0`. -/// let cpu0_started =3D io.read(CPU_CTL::of::()); -/// -/// // Stop `Cpu0`. -/// io.write(WithBase::of::(), CPU_CTL::zeroed()); -/// # } -/// -/// // Aliases can also be defined for relative register. -/// register! { -/// base: Region<0x1000>; -/// -/// /// Alias to CPU core control. -/// pub CPU_CTL_ALIAS(u32) =3D> CpuCtlBase + CPU_CTL { -/// /// Start the aliased CPU core. -/// 1:1 alias_start; -/// } -/// } -/// -/// # fn test2(io: Mmio<'_, Region<0x1000>>) { -/// // Start the aliased `CPU0`, leaving its other fields untouched. -/// io.update(CPU_CTL_ALIAS::of::(), |r| r.with_alias_start(true)); -/// # } -/// ``` -/// /// ## Arrays of registers /// /// Some I/O areas contain consecutive registers that share the same field= layout. These areas can @@ -725,118 +469,6 @@ fn into_io_op(self) -> (FixedRegisterLoc, T) { /// # Ok(()) /// # } /// ``` -/// -/// ## Relative arrays of registers -/// -/// Combining the two features described in the sections above, arrays of = registers accessible from -/// a base can also be defined: -/// -/// ```ignore -/// register! { -/// ... -/// pub RELATIVE_REGISTER_ARRAY(u8)[10, stride =3D 4] @ Base + 0x100 { -/// ... -/// } -/// } -/// ``` -/// -/// Like relative registers, they implement the [`WithBase`] trait. Howeve= r the return value of -/// [`WithBase::of`] cannot be used directly as a location and must be fur= ther specified using the -/// [`at`](RelativeRegisterLoc::at) method. -/// -/// ```no_run -/// use kernel::{ -/// io::{ -/// register, -/// register::{ -/// RegisterBase, -/// WithBase, -/// }, -/// Io, -/// Region, -/// }, -/// }; -/// # use kernel::io::Mmio; -/// # fn get_scratch_idx() -> usize { -/// # 0x15 -/// # } -/// -/// // Type used as parameter of `RegisterBase` to specify the base. -/// pub struct CpuCtlBase; -/// -/// // ZST describing `CPU0`. -/// struct Cpu0; -/// impl RegisterBase for Cpu0 { -/// const BASE: usize =3D 0x100; -/// } -/// -/// // ZST describing `CPU1`. -/// struct Cpu1; -/// impl RegisterBase for Cpu1 { -/// const BASE: usize =3D 0x200; -/// } -/// -/// // 64 per-cpu scratch registers, arranged as a contiguous array. -/// register! { -/// base: Region<0x1000>; -/// -/// /// Per-CPU scratch registers. -/// pub CPU_SCRATCH(u32)[64] @ CpuCtlBase + 0x00000080 { -/// 31:0 value; -/// } -/// } -/// -/// # fn test(io: Mmio<'_, Region<0x1000>>) -> Result<(), Error> { -/// // Read scratch register 0 of CPU0. -/// let scratch =3D io.read(CPU_SCRATCH::of::().at(0)); -/// -/// // Write the retrieved value into scratch register 15 of CPU1. -/// io.write(WithBase::of::().at(15), scratch); -/// -/// // This won't build. -/// // let cpu0_scratch_128 =3D io.read(CPU_SCRATCH::of::().at(128))= .value(); -/// -/// // Runtime-obtained array index. -/// let scratch_idx =3D get_scratch_idx(); -/// // Access on a runtime index returns an error if it is out-of-bounds. -/// let cpu0_scratch =3D io.read( -/// CPU_SCRATCH::of::().try_at(scratch_idx).ok_or(EINVAL)? -/// ).value(); -/// # Ok(()) -/// # } -/// -/// // Alias to `SCRATCH[8]` used to convey the firmware exit code. -/// register! { -/// base: Region<0x1000>; -/// -/// /// Per-CPU firmware exit status code. -/// pub CPU_FIRMWARE_STATUS(u32) =3D> CpuCtlBase + CPU_SCRATCH[8] { -/// 7:0 status; -/// } -/// } -/// -/// // Non-contiguous relative register arrays can be defined by adding a = stride parameter. -/// // Here, each of the 16 registers of the array is separated by 8 bytes= , meaning that the -/// // registers of the two declarations below are interleaved. -/// register! { -/// base: Region<0x1000>; -/// -/// /// Scratch registers bank 0. -/// pub CPU_SCRATCH_INTERLEAVED_0(u32)[16, stride =3D 8] @ CpuCtlBase = + 0x00000d00 { -/// 31:0 value; -/// } -/// -/// /// Scratch registers bank 1. -/// pub CPU_SCRATCH_INTERLEAVED_1(u32)[16, stride =3D 8] @ CpuCtlBase = + 0x00000d04 { -/// 31:0 value; -/// } -/// } -/// -/// # fn test2(io: Mmio<'_, Region<0x1000>>) -> Result<(), Error> { -/// let cpu0_status =3D io.read(CPU_FIRMWARE_STATUS::of::()).status(= ); -/// # Ok(()) -/// # } -/// ``` #[macro_export] macro_rules! register { // Entry point for the macro, allowing multiple registers to be define= d in one call. @@ -847,7 +479,7 @@ macro_rules! register { $( $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) $([ $size:expr $(, stride =3D $stride:expr)? ])? - $(@ $($base:ident +)? $offset:literal)? + $(@ $offset:literal)? $(=3D> $alias:ident $(+ $alias_offset:ident)? $([$alias_id= x:expr])? )? { $($fields:tt)* } )* @@ -855,7 +487,7 @@ macro_rules! register { $( $crate::register!( @reg [$reg_base] $(#[$attr])* $vis $name ($storage) $([$size $= (, stride =3D $stride)?])? - $(@ $($base +)? $offset)? + $(@ $offset)? $(=3D> $alias $(+ $alias_offset)? $([$alias_idx])? )? { $($fields)* } ); @@ -887,30 +519,6 @@ macro_rules! register { $crate::register!(@io_fixed $(#[$attr])* $vis $name($storage)); }; =20 - // Creates a register at a relative offset from a base address provide= r. - ( - @reg [$reg_base:ty] - $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) @ $base:i= dent + $offset:literal - { $($fields:tt)* } - ) =3D> { - $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storag= e) { $($fields)* }); - $crate::register!(@io_base [$reg_base] $name($storage) @ $offset); - $crate::register!(@io_relative $vis $name($storage) @ $base); - }; - - // Creates an alias register of relative offset register `alias` with = its own fields. - ( - @reg [$reg_base:ty] - $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) =3D> $bas= e:ident + $alias:ident - { $($fields:tt)* } - ) =3D> { - $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storag= e) { $($fields)* }); - $crate::register!(@io_base [$reg_base] - $name($storage) @ <$alias as $crate::io::register::Register>::= OFFSET - ); - $crate::register!(@io_relative $vis $name($storage) @ $base); - }; - // Creates an array of registers at a fixed offset of the MMIO space. ( @reg [$reg_base:ty] $(#[$attr:meta])* $vis:vis $name:ident ($stora= ge:ty) @@ -954,51 +562,6 @@ macro_rules! register { $crate::register!(@io_fixed $(#[$attr])* $vis $name($storage)); }; =20 - // Creates an array of registers at a relative offset from a base addr= ess provider. - ( - @reg [$reg_base:ty] $(#[$attr:meta])* $vis:vis $name:ident ($stora= ge:ty) - [ $size:expr, stride =3D $stride:expr ] - @ $base:ident + $offset:literal { $($fields:tt)* } - ) =3D> { - $crate::build_assert::static_assert!(::core::mem::size_of::<$stora= ge>() <=3D $stride); - - $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storag= e) { $($fields)* }); - $crate::register!(@io_base [$reg_base] $name($storage) @ $offset); - $crate::register!( - @io_relative_array $vis $name($storage) [ $size, stride =3D $s= tride ] @ $base + $offset - ); - }; - - // Shortcut for contiguous array of relative registers (stride =3D=3D = size of element). - ( - @reg [$reg_base:ty] $(#[$attr:meta])* $vis:vis $name:ident ($stora= ge:ty) [ $size:expr ] - @ $base:ident + $offset:literal { $($fields:tt)* } - ) =3D> { - $crate::register!(@reg [$reg_base] - $(#[$attr])* $vis $name($storage) [ $size, stride =3D ::core::= mem::size_of::<$storage>() ] - @ $base + $offset { $($fields)* } - ); - }; - - // Creates an alias of register `idx` of relative array of registers `= alias` with its own - // fields. - ( - @reg [$reg_base:ty] $(#[$attr:meta])* $vis:vis $name:ident ($stora= ge:ty) - =3D> $base:ident + $alias:ident [ $idx:expr ] { $($fields:tt)*= } - ) =3D> { - $crate::build_assert::static_assert!( - $idx < <$alias as $crate::io::register::RegisterArray>::SIZE - ); - - $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storag= e) { $($fields)* }); - $crate::register!( - @io_base [$reg_base] $name($storage) @ - <$alias as $crate::io::register::Register>::OFFSET + - $idx * <$alias as $crate::io::register::RegisterArray>::ST= RIDE - ); - $crate::register!(@io_relative $vis $name($storage) @ $base); - }; - // Generates the bitfield for the register. // // `#[allow(non_camel_case_types)]` is added since register names typi= cally use @@ -1031,15 +594,6 @@ impl $crate::io::register::FixedRegister for $name {} $crate::io::register::FixedRegisterLoc::<$name>::new(); }; =20 - // Implementations of relative registers. - (@io_relative $vis:vis $name:ident ($storage:ty) @ $base:ident) =3D> { - impl $crate::io::register::WithBase for $name { - type BaseFamily =3D $base; - } - - impl $crate::io::register::RelativeRegister for $name {} - }; - // Implementations of register arrays. (@io_array $vis:vis $name:ident ($storage:ty) [ $size:expr, stride =3D= $stride:expr ]) =3D> { impl $crate::io::register::Array for $name {} @@ -1049,21 +603,4 @@ impl $crate::io::register::RegisterArray for $name { const STRIDE: usize =3D $stride; } }; - - // Implementations of relative array registers. - ( - @io_relative_array $vis:vis $name:ident ($storage:ty) [ $size:expr= , stride =3D $stride:expr ] - @ $base:ident + $offset:literal - ) =3D> { - impl $crate::io::register::WithBase for $name { - type BaseFamily =3D $base; - } - - impl $crate::io::register::RegisterArray for $name { - const SIZE: usize =3D $size; - const STRIDE: usize =3D $stride; - } - - impl $crate::io::register::RelativeRegisterArray for $name {} - }; } --=20 2.54.0