[PATCH v3 6/7] test: dm: add comprehensive tests for NVMEM bit field operations
Aswin Murugan
aswin.murugan at oss.qualcomm.com
Mon Mar 30 19:14:18 CEST 2026
Add a mock I2C EEPROM device (nvmem-test at 50) to the sandbox device tree
to support NVMEM bit field operation testing.
Add test coverage for NVMEM bit field read and write operations to
validate the new bit field support in the NVMEM subsystem.
Test cases include:
- 1-byte cell with 7-bit field
- 2-byte cell with 12-bit field spanning a byte boundary
- 4-byte cell without a bit field (legacy byte-level access)
- 4-byte cell with a 16-bit field in the upper 2 bytes
Error validation tests cover:
- Bit field exceeding the cell size
- Bit field exceeding the 32-bit maximum
- Invalid bit_offset and nbits combinations
- Buffer size mismatch in non-bit-field mode
The tests verify:
- Correct bit extraction during read operations
- Read-modify-write behavior preserving unrelated bits
- Proper error handling for invalid configurations
Signed-off-by: Aswin Murugan <aswin.murugan at oss.qualcomm.com>
---
arch/sandbox/dts/test.dts | 12 ++++
test/dm/reboot-mode.c | 137 ++++++++++++++++++++++++++++++++++++++
2 files changed, 149 insertions(+)
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 762c1d9bbe2..4fb4d0a8ef5 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -959,6 +959,11 @@
sandbox,filename = "i2c.bin";
sandbox,size = <256>;
};
+ emul_nvmem_test: emul-nvmem-test {
+ compatible = "sandbox,i2c-eeprom";
+ sandbox,filename = "nvmem-test.bin";
+ sandbox,size = <256>;
+ };
emul0: emul0 {
compatible = "sandbox,i2c-rtc-emul";
};
@@ -976,6 +981,13 @@
reg = <0x41>;
sandbox,emul = <&emul_pmic1>;
};
+
+ /* Mock NVMEM device for bit field testing */
+ nvmem-test at 50 {
+ reg = <0x50>;
+ compatible = "i2c-eeprom";
+ sandbox,emul = <&emul_nvmem_test>;
+ };
};
i3c0 {
diff --git a/test/dm/reboot-mode.c b/test/dm/reboot-mode.c
index 9a3b2bf0a43..8e6634339a8 100644
--- a/test/dm/reboot-mode.c
+++ b/test/dm/reboot-mode.c
@@ -15,6 +15,8 @@
#include <test/ut.h>
#include <rtc.h>
#include <linux/byteorder/generic.h>
+#include <nvmem.h>
+#include <misc.h>
static int dm_test_reboot_mode_gpio(struct unit_test_state *uts)
{
@@ -66,3 +68,138 @@ static int dm_test_reboot_mode_rtc(struct unit_test_state *uts)
}
DM_TEST(dm_test_reboot_mode_rtc,
UTF_PROBE_TEST | UTF_SCAN_FDT | UTF_FLAT_TREE);
+
+static int nvmem_test_write_raw(struct udevice *dev, uint offset,
+ const void *buf, uint size)
+{
+ return misc_write(dev, offset, buf, size);
+}
+
+static int nvmem_test_read_raw(struct udevice *dev, uint offset,
+ void *buf, uint size)
+{
+ return misc_read(dev, offset, buf, size);
+}
+
+/* Test NVMEM bit field operations */
+static int dm_test_nvmem_bitfield(struct unit_test_state *uts)
+{
+ struct udevice *nvmem_dev;
+ struct nvmem_cell cell;
+ u32 value;
+ u8 hw_value_u8;
+ u16 hw_value_u16;
+ u32 hw_value_u32;
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_I2C_EEPROM,
+ "nvmem-test at 50", &nvmem_dev));
+
+ cell.nvmem = nvmem_dev;
+
+ /* Test reg = <0x0 0x1>; bits = <1 7>: */
+ cell.offset = 0x0;
+ cell.size = 1;
+ cell.bit_offset = 1;
+ cell.nbits = 7;
+ hw_value_u8 = 0x01;
+ ut_assertok(nvmem_test_write_raw(nvmem_dev, cell.offset, &hw_value_u8, 1));
+ value = 0x7F;
+ ut_assertok(nvmem_cell_write(&cell, &value, sizeof(value)));
+ value = 0;
+ ut_assertok(nvmem_cell_read(&cell, &value, sizeof(value)));
+ ut_asserteq(0x7F, value);
+ ut_assertok(nvmem_test_read_raw(nvmem_dev, cell.offset, &hw_value_u8, 1));
+ ut_asserteq(0xFF, hw_value_u8);
+
+ /* Test reg = <0x18 0x4>; bits = <4 12>: Spanning byte boundary */
+ cell.offset = 0x18;
+ cell.size = 4;
+ cell.bit_offset = 4;
+ cell.nbits = 12;
+ hw_value_u16 = 0x000F;
+ ut_assertok(nvmem_test_write_raw(nvmem_dev, cell.offset, (u8 *)&hw_value_u16, 2));
+ value = 0xFFF;
+ ut_assertok(nvmem_cell_write(&cell, &value, sizeof(value)));
+ ut_assertok(nvmem_test_read_raw(nvmem_dev, cell.offset, (u8 *)&hw_value_u16, 2));
+ ut_asserteq(0xFFFF, hw_value_u16);
+
+ /* Test reg = <0x9 0x4>: Full 4-byte access without bit field */
+ cell.offset = 0x9;
+ cell.bit_offset = 0;
+ cell.nbits = 0;
+ value = 0x12345678;
+ ut_assertok(nvmem_cell_write(&cell, &value, sizeof(value)));
+ value = 0;
+ ut_assertok(nvmem_cell_read(&cell, &value, sizeof(value)));
+ ut_asserteq(0x12345678, value);
+
+ /* Test reg = <0xc 0x4>; bits = <16 16>: Upper 2 bytes */
+ cell.offset = 0xc;
+ cell.bit_offset = 16;
+ cell.nbits = 16;
+ hw_value_u32 = 0x0000FFFF;
+ ut_assertok(nvmem_test_write_raw(nvmem_dev, cell.offset, (u8 *)&hw_value_u32, 4));
+ value = 0xFFFF;
+ ut_assertok(nvmem_cell_write(&cell, &value, sizeof(value)));
+ ut_assertok(nvmem_test_read_raw(nvmem_dev, cell.offset, (u8 *)&hw_value_u32, 4));
+ ut_asserteq(0xFFFFFFFF, hw_value_u32);
+
+ return 0;
+}
+DM_TEST(dm_test_nvmem_bitfield,
+ UTF_PROBE_TEST | UTF_SCAN_FDT | UTF_FLAT_TREE);
+
+/* Test NVMEM error handling for invalid configurations */
+static int dm_test_nvmem_bitfield_errors(struct unit_test_state *uts)
+{
+ struct udevice *nvmem_dev;
+ struct nvmem_cell cell;
+ u32 value;
+ int ret;
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_I2C_EEPROM,
+ "nvmem-test at 50", &nvmem_dev));
+
+ /* Test bit field exceeding cell size */
+ cell.nvmem = nvmem_dev;
+ cell.offset = 0xd;
+ cell.size = 1;
+ cell.bit_offset = 0;
+ cell.nbits = 9;
+
+ value = 0xFF;
+ ret = nvmem_cell_write(&cell, &value, sizeof(value));
+ ut_assert(ret < 0);
+
+ /* Test bit field exceeding 32 bits */
+ cell.size = 4;
+ cell.bit_offset = 0;
+ cell.nbits = 33;
+
+ ret = nvmem_cell_write(&cell, &value, sizeof(value));
+ ut_assert(ret < 0);
+
+ /* Test invalid bit_offset + nbits */
+ cell.size = 1;
+ cell.bit_offset = 7;
+ cell.nbits = 2;
+
+ ret = nvmem_cell_write(&cell, &value, sizeof(value));
+ ut_assert(ret < 0);
+
+ /* Test nbits=0 requires buffer size == cell size */
+ cell.size = 1;
+ cell.bit_offset = 0;
+ cell.nbits = 0;
+
+ value = 0xFF;
+ ret = nvmem_cell_write(&cell, &value, sizeof(value));
+ ut_assert(ret < 0);
+
+ ret = nvmem_cell_read(&cell, &value, sizeof(value));
+ ut_assert(ret < 0);
+
+ return 0;
+}
+DM_TEST(dm_test_nvmem_bitfield_errors,
+ UTF_PROBE_TEST | UTF_SCAN_FDT | UTF_FLAT_TREE);
--
2.34.1
More information about the U-Boot
mailing list