[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250824135954.2243774-2-joelagnelf@nvidia.com>
Date: Sun, 24 Aug 2025 09:59:53 -0400
From: Joel Fernandes <joelagnelf@...dia.com>
To: linux-kernel@...r.kernel.org,
Danilo Krummrich <dakr@...nel.org>,
Alexandre Courbot <acourbot@...dia.com>,
David Airlie <airlied@...il.com>,
Simona Vetter <simona@...ll.ch>
Cc: John Hubbard <jhubbard@...dia.com>,
Alistair Popple <apopple@...dia.com>,
Joel Fernandes <joelagnelf@...dia.com>,
nouveau@...ts.freedesktop.org,
dri-devel@...ts.freedesktop.org
Subject: [PATCH 2/2] nova-core: Add KUNIT tests for bitstruct
Add KUNIT tests to make sure the macros are working correctly.
Signed-off-by: Joel Fernandes <joelagnelf@...dia.com>
---
drivers/gpu/nova-core/bitstruct.rs | 198 +++++++++++++++++++++++++++++
1 file changed, 198 insertions(+)
diff --git a/drivers/gpu/nova-core/bitstruct.rs b/drivers/gpu/nova-core/bitstruct.rs
index 661a75da0a9c..7ce2f4ecfbba 100644
--- a/drivers/gpu/nova-core/bitstruct.rs
+++ b/drivers/gpu/nova-core/bitstruct.rs
@@ -147,3 +147,201 @@ impl $struct_name {
}
};
}
+
+#[kunit_tests(nova_core_bitstruct)]
+mod kunit_tests {
+ // These are dummy structures just for testing (not real hardware).
+ bitstruct! {
+ #[repr(u64)]
+ struct TestPageTableEntry {
+ 0:0 present as bool,
+ 1:1 writable as bool,
+ 11:9 available as u8,
+ 51:12 pfn as u64,
+ 61:52 available2 as u16,
+ }
+ }
+
+ bitstruct! {
+ #[repr(u16)]
+ struct TestControlRegister {
+ 0:0 enable as bool,
+ 3:1 mode as u8,
+ 7:4 priority as u8,
+ 15:8 channel as u8,
+ }
+ }
+
+ bitstruct! {
+ #[repr(u8)]
+ struct TestStatusRegister {
+ 0:0 ready as bool,
+ 1:1 error as bool,
+ 3:2 state as u8,
+ 7:4 reserved as u8,
+ }
+ }
+
+ #[test]
+ fn test_single_bits() {
+ let mut pte = TestPageTableEntry::default();
+
+ // Test initial state of boolean fields - expected false
+ assert!(!pte.present());
+ assert!(!pte.writable());
+
+ pte.set_present(true);
+ assert!(pte.present());
+
+ pte.set_writable(true);
+ assert!(pte.writable());
+
+ pte.set_writable(false);
+ assert!(!pte.writable());
+
+ // Test available field (3 bits)
+ assert_eq!(pte.available(), 0);
+ pte.set_available(0x5);
+ assert_eq!(pte.available(), 0x5);
+ }
+
+ #[test]
+ fn test_range_fields() {
+ let mut pte = TestPageTableEntry::default();
+
+ pte.set_pfn(0x123456);
+ assert_eq!(pte.pfn(), 0x123456);
+
+ pte.set_available(0x7);
+ assert_eq!(pte.available(), 0x7);
+
+ pte.set_available2(0x3FF);
+ assert_eq!(pte.available2(), 0x3FF);
+
+ let max_pfn = (1u64 << 40) - 1; // 40 bits for pfn
+ pte.set_pfn(max_pfn);
+ assert_eq!(pte.pfn(), max_pfn);
+ }
+
+ #[test]
+ fn test_builder_pattern() {
+ let pte = TestPageTableEntry::default()
+ .with_present(true)
+ .with_writable(true)
+ .with_available(0x7)
+ .with_pfn(0xABCDEF)
+ .with_available2(0x3FF);
+
+ assert!(pte.present());
+ assert!(pte.writable());
+ assert_eq!(pte.available(), 0x7);
+ assert_eq!(pte.pfn(), 0xABCDEF);
+ assert_eq!(pte.available2(), 0x3FF);
+ }
+
+ #[test]
+ fn test_raw_operations() {
+ let raw_value = 0x3FF0000000123E03u64;
+ let pte = TestPageTableEntry::from_raw(raw_value);
+ assert_eq!(pte.into_raw(), raw_value);
+
+ assert!(pte.present()); // bit 0
+ assert!(pte.writable()); // bit 1
+ assert_eq!(pte.available(), 0x7); // bits 9-11: 0xE00 >> 9 = 0x7
+ assert_eq!(pte.pfn(), 0x123); // bits 12-51: 0x123 << 12
+ assert_eq!(pte.available2(), 0x3FF); // bits 52-61: 0x3FF << 52
+ }
+
+ #[test]
+ fn test_u16_bitstruct() {
+ let mut ctrl = TestControlRegister::default();
+
+ // Test initial state
+ assert!(!ctrl.enable());
+ assert_eq!(ctrl.mode(), 0);
+ assert_eq!(ctrl.priority(), 0);
+ assert_eq!(ctrl.channel(), 0);
+
+ ctrl.set_enable(true);
+ assert!(ctrl.enable());
+
+ ctrl.set_mode(0x5);
+ assert_eq!(ctrl.mode(), 0x5);
+
+ ctrl.set_priority(0xF);
+ assert_eq!(ctrl.priority(), 0xF);
+
+ ctrl.set_channel(0xAB);
+ assert_eq!(ctrl.channel(), 0xAB);
+
+ // Test u16 builder pattern
+ let ctrl2 = TestControlRegister::default()
+ .with_enable(true)
+ .with_mode(0x3)
+ .with_priority(0x8)
+ .with_channel(0x42);
+
+ assert!(ctrl2.enable());
+ assert_eq!(ctrl2.mode(), 0x3);
+ assert_eq!(ctrl2.priority(), 0x8);
+ assert_eq!(ctrl2.channel(), 0x42);
+
+ // Test u16 raw operations
+ let raw_value: u16 = 0x4281;
+ let ctrl3 = TestControlRegister::from_raw(raw_value);
+ assert_eq!(ctrl3.into_raw(), raw_value);
+ assert!(ctrl3.enable());
+ assert_eq!(ctrl3.priority(), 0x8);
+ assert_eq!(ctrl3.channel(), 0x42);
+ }
+
+ #[test]
+ fn test_u8_bitstruct() {
+ let mut status = TestStatusRegister::default();
+
+ // Test initial state
+ assert!(!status.ready());
+ assert!(!status.error());
+ assert_eq!(status.state(), 0);
+ assert_eq!(status.reserved(), 0);
+
+ status.set_ready(true);
+ assert!(status.ready());
+
+ status.set_error(true);
+ assert!(status.error());
+
+ status.set_state(0x3);
+ assert_eq!(status.state(), 0x3);
+
+ status.set_reserved(0xA);
+ assert_eq!(status.reserved(), 0xA);
+
+ // Test u8 builder pattern
+ let status2 = TestStatusRegister::default()
+ .with_ready(true)
+ .with_state(0x2)
+ .with_reserved(0x5);
+
+ assert!(status2.ready());
+ assert!(!status2.error());
+ assert_eq!(status2.state(), 0x2);
+ assert_eq!(status2.reserved(), 0x5);
+
+ // Test u8 raw operations
+ let raw_value: u8 = 0x59;
+ let status3 = TestStatusRegister::from_raw(raw_value);
+ assert_eq!(status3.into_raw(), raw_value);
+ assert!(status3.ready());
+ assert!(!status3.error());
+ assert_eq!(status3.state(), 0x2);
+ assert_eq!(status3.reserved(), 0x5);
+
+ // Test max raw value - all bits set
+ let status4 = TestStatusRegister::from_raw(0xFF);
+ assert!(status4.ready());
+ assert!(status4.error());
+ assert_eq!(status4.state(), 0x3);
+ assert_eq!(status4.reserved(), 0xF);
+ }
+}
--
2.34.1
Powered by blists - more mailing lists