@@ -444,6 +444,88 @@ pub const Value = struct {
444444 try shared .customExpectEqual (iter .next (), 0xFFFFFFFFFFFFFFFF );
445445 try shared .customExpectEqual (iter .next (), null );
446446 }
447+
448+ pub const RegValue = struct {
449+ address : u64 ,
450+ size : u64 ,
451+ };
452+
453+ /// Iterate over the value as a list of `RegValue`s.
454+ ///
455+ /// `address_cells` and `size_cells` must be less than or equal to 2.
456+ pub fn regIterator (self : Value , address_cells : u32 , size_cells : u32 ) ListIteratorError ! RegIterator {
457+ const size_of_one_element = (address_cells + size_cells ) * @sizeOf (u32 );
458+ if (self ._raw .len % size_of_one_element != 0 ) {
459+ @branchHint (.cold );
460+ return error .SizeNotMultiple ;
461+ }
462+
463+ // TODO: support address_cells and size_cells greater than two
464+ if (address_cells > 2 or size_cells > 2 ) {
465+ @panic ("address_cells or size_cells greater than two is not supported" );
466+ }
467+
468+ return .{
469+ .cells = std .mem .bytesAsSlice (u32 , self ._raw ),
470+ .address_cells = address_cells ,
471+ .size_cells = size_cells ,
472+ };
473+ }
474+
475+ test regIterator {
476+ const dt : DeviceTree = try .fromSlice (shared .test_dtb );
477+
478+ const flash_node = (try dt .firstMatchingNode (.{ .name = "flash" })).? .node ;
479+
480+ const reg_property = (try flash_node .firstMatchingProperty (dt , .{
481+ .name = "reg" ,
482+ })).? ;
483+
484+ var iter = try reg_property .value .regIterator (2 , 2 );
485+ try shared .customExpectEqual (iter .next (), .{
486+ .address = 0x20000000 ,
487+ .size = 0x2000000 ,
488+ });
489+ try shared .customExpectEqual (iter .next (), .{
490+ .address = 0x22000000 ,
491+ .size = 0x2000000 ,
492+ });
493+ try shared .customExpectEqual (iter .next (), null );
494+ }
495+
496+ pub const RegIterator = struct {
497+ cells : []align (1 ) const u32 ,
498+
499+ address_cells : u32 ,
500+ size_cells : u32 ,
501+
502+ pub fn next (self : * RegIterator ) ? RegValue {
503+ if (self .cells .len == 0 ) return null ;
504+
505+ // TODO: support address_cells and size_cells greater than two
506+ std .debug .assert (self .address_cells <= 2 );
507+ std .debug .assert (self .size_cells <= 2 );
508+
509+ var address : u64 = 0 ;
510+ for (0.. self .address_cells ) | i | {
511+ const value : u64 = shared .bigToNative (u32 , self .cells [i ]);
512+ address |= value << @intCast ((self .address_cells - i - 1 ) * 32 );
513+ }
514+ self .cells = self .cells [self .address_cells .. ];
515+
516+ var size : u64 = 0 ;
517+ for (0.. self .size_cells ) | i | {
518+ const value : u64 = shared .bigToNative (u32 , self .cells [i ]);
519+ size |= value << @intCast ((self .size_cells - i - 1 ) * 32 );
520+ }
521+ self .cells = self .cells [self .size_cells .. ];
522+
523+ return .{
524+ .address = address ,
525+ .size = size ,
526+ };
527+ }
528+ };
447529};
448530
449531pub const Match = union (enum ) {
0 commit comments