icdutil.addrmap module
Address Map.
- class icdutil.addrmap.AddrMap(addrwidth: Optional[int] = None, is_sub: bool = False, allow_overlapping: bool = False, AddrMap__addrranges: list = _Nothing.NOTHING)[source]
Bases:
objectAddress Map.
- Keyword Arguments:
addrwidth (int) – Address width. Calculated automatically.
is_sub (bool) – Handle sub addresses only. Just the minimum number of address bits is evaluated.
default (#) – Default item, returned on unallocated address ranges.
allow_overlapping (bool) – Allow overlapping address ranges.
>>> a = AddrMap() >>> a AddrMap() >>> a.add('T', size=0x400) AddrRange('T', 0x0, '1 KB') >>> a.add('A', 0x5000, 0x1000) AddrRange('A', 0x5000, '4 KB') >>> a.add('B', 0x2000, 0x1000) AddrRange('B', 0x2000, '4 KB') >>> a.add('C', 0xD000, 0x800) AddrRange('C', 0xD000, '2 KB') >>> a.add('Z', size=0x1000) AddrRange('Z', 0xE000, '4 KB') >>> a.add('X', 0xF0800000, 1024*1024*3) AddrRange('X', 0xF0800000, '3 MB')
Addresses can be used only once:
>>> a.add('D', 0xE400, 0x0400) Traceback (most recent call last): ... icdutil.addrmap.Conflict: AddrRange('D', 0xE400, '1 KB'): overlaps with AddrRange('Z', 0xE000, '4 KB'). >>> a.add('D', 0x2000) Traceback (most recent call last): ... icdutil.addrmap.Conflict: AddrRange('D', 0x2000, '1 byte'): overlaps with AddrRange('B', 0x2000, '4 KB'). >>> a.add('D', 0x2000, '8 KB') Traceback (most recent call last): ... icdutil.addrmap.Conflict: AddrRange('D', 0x2000, '8 KB'): overlaps with AddrRange('B', 0x2000, '4 KB'). >>> a.add('D', 0x1800, '4 KB') Traceback (most recent call last): ... icdutil.addrmap.Conflict: AddrRange('D', 0x1800, '4 KB'): overlaps with AddrRange('B', 0x2000, '4 KB').
An iteration will serve
AddrRangeobjects sorted by baseaddr:>>> for addrrange in a: ... addrrange AddrRange('T', 0x0, '1 KB') AddrRange('B', 0x2000, '4 KB') AddrRange('A', 0x5000, '4 KB') AddrRange('C', 0xD000, '2 KB') AddrRange('Z', 0xE000, '4 KB') AddrRange('X', 0xF0800000, '3 MB')
The size is defined by the numer of entries:
>>> len(a) 6
By using a default the gaps are filled with this item:
>>> for addrrange in a.get(default='d'): ... addrrange AddrRange('T', 0x0, '1 KB') AddrRange('d', 0x400, '7 KB') AddrRange('B', 0x2000, '4 KB') AddrRange('d', 0x3000, '8 KB') AddrRange('A', 0x5000, '4 KB') AddrRange('d', 0x6000, '28 KB') AddrRange('C', 0xD000, '2 KB') AddrRange('d', 0xD800, '2 KB') AddrRange('Z', 0xE000, '4 KB') AddrRange('d', 0xF000, '3.76 GB') AddrRange('X', 0xF0800000, '3 MB') AddrRange('d', 0xF0B00000, '245 MB') >>> len(tuple(a.get('d'))) 12
The is_sub attribute defines the address range defaults:
>>> b = AddrMap(addrwidth=32, is_sub=True) >>> b AddrMap(addrwidth=32, is_sub=True) >>> b.add('T', size=0x400) AddrRange('T', 0x00000000, '1 KB', addrwidth=32, is_sub=True) >>> b.add('A', 0x5000, 0x1000) AddrRange('A', 0x00005000, '4 KB', addrwidth=32, is_sub=True) >>> b.add('B', 0x2000, 0x1000) AddrRange('B', 0x00002000, '4 KB', addrwidth=32, is_sub=True) >>> b.add('C', 0xD000, 0x800) AddrRange('C', 0x0000D000, '2 KB', addrwidth=32, is_sub=True) >>> b.add('Z', size=0x1000) AddrRange('Z', 0x0000E000, '4 KB', addrwidth=32, is_sub=True) >>> b.add('X', 0xF0800000, 1024*1024*3, is_sub=False) AddrRange('X', 0xF0800000, '3 MB', addrwidth=32) >>> for addrrange in b: ... addrrange AddrRange('T', 0x00000000, '1 KB', addrwidth=32, is_sub=True) AddrRange('B', 0x00002000, '4 KB', addrwidth=32, is_sub=True) AddrRange('A', 0x00005000, '4 KB', addrwidth=32, is_sub=True) AddrRange('C', 0x0000D000, '2 KB', addrwidth=32, is_sub=True) AddrRange('Z', 0x0000E000, '4 KB', addrwidth=32, is_sub=True) AddrRange('X', 0xF0800000, '3 MB', addrwidth=32)
The allow_overlapping attibute allows address ranges to intersect.
>>> c = AddrMap(allow_overlapping=True) >>> c AddrMap(allow_overlapping=True) >>> c.add('L', size=0x1000) AddrRange('L', 0x0, '4 KB') >>> c.add('R', 0x400, size=0x1000) AddrRange('R', 0x400, '4 KB') >>> c.add('M', 0x200, '2 KB') AddrRange('M', 0x200, '2 KB') >>> for addrrange in c: ... addrrange AddrRange('L', 0x0, '4 KB') AddrRange('M', 0x200, '2 KB') AddrRange('R', 0x400, '4 KB')
- add(item, baseaddr: Optional[int] = None, size: int = 1, is_sub: Optional[bool] = None, align: Optional[int] = None, startsearch: Optional[int] = None) AddrRange[source]
Add item for address decoding.
- Parameters:
item – any object managed by this address decoder
- Keyword Arguments:
baseaddr – Base address. Behind last item by default.
size – Size in bytes
is_sub – Overwrite sub address attribute.
align – Alignment
startsearch – Search of free address at given number (if baseaddr is None)
>>> a = AddrMap() >>> a.add('A', baseaddr=0x3000, size='4 KB') AddrRange('A', 0x3000, '4 KB') >>> a.add('B', 0x1000, '1 KB', is_sub=True) AddrRange('B', 0x1000, '1 KB', is_sub=True) >>> a.add('C', 0x4500, '4 KB', align=0x1000) AddrRange('C', 0x5000, '4 KB')
- property addrspace: Optional[int]
Allocated Address space.
>>> a = AddrMap() >>> a.addrspace >>> a.add('A', 0x5000, '4 KB') AddrRange('A', 0x5000, '4 KB') >>> str(a.addrspace) '0x1000' >>> a.add('B', 0x2000, '4 KB') AddrRange('B', 0x2000, '4 KB') >>> str(a.addrspace) '0x4000' >>> a.add('C', 0x7000, 13) AddrRange('C', 0x7000, '13 bytes') >>> str(a.addrspace) '0x500D'
- addrwidth: Optional[int]
- allow_overlapping: bool
- cut(baseaddr, size=1) AddrMap[source]
Cut out address range from baseaddr for size.
Return address map with cut address ranges.
>>> a = AddrMap() >>> a.add('A', 0x0000, 0x1000) AddrRange('A', 0x0, '4 KB') >>> a.add('B', 0x1000, 0x1000) AddrRange('B', 0x1000, '4 KB') >>> a.add('C', 0x2000, 0x1000) AddrRange('C', 0x2000, '4 KB') >>> a.add('D', 0x3000, 0x1000) AddrRange('D', 0x3000, '4 KB') >>> print(a.get_overview()) Baseaddr Size Sub Item ---------- ------------- ----- ------ 0x0 0x1000 (4 KB) No 'A' 0x1000 0x1000 (4 KB) No 'B' 0x2000 0x1000 (4 KB) No 'C' 0x3000 0x1000 (4 KB) No 'D'
Cut multiple address ranges
>>> c = a.cut(0x1800, 0x1000) >>> print(a.get_overview()) Baseaddr Size Sub Item ---------- ------------- ----- ------ 0x0 0x1000 (4 KB) No 'A' 0x1000 0x800 (2 KB) No 'B' 0x2800 0x800 (2 KB) No 'C' 0x3000 0x1000 (4 KB) No 'D' >>> print(c.get_overview()) Baseaddr Size Sub Item ---------- ------------ ----- ------ 0x1800 0x800 (2 KB) No 'B' 0x2000 0x800 (2 KB) No 'C'
Cut at the front
>>> c = a.cut(0, 0x1000) >>> print(a.get_overview()) Baseaddr Size Sub Item ---------- ------------- ----- ------ 0x1000 0x800 (2 KB) No 'B' 0x2800 0x800 (2 KB) No 'C' 0x3000 0x1000 (4 KB) No 'D' >>> print(c.get_overview()) Baseaddr Size Sub Item ---------- ------------- ----- ------ 0x0 0x1000 (4 KB) No 'A'
Cut at the end
>>> c = a.cut(0x3C00, 0x1000) >>> print(a.get_overview()) Baseaddr Size Sub Item ---------- ------------ ----- ------ 0x1000 0x800 (2 KB) No 'B' 0x2800 0x800 (2 KB) No 'C' 0x3000 0xC00 (3 KB) No 'D' >>> print(c.get_overview()) Baseaddr Size Sub Item ---------- ------------ ----- ------ 0x3C00 0x400 (1 KB) No 'D'
Cut exactly one
>>> c = a.cut(0x2800, '2 KB') >>> print(a.get_overview()) Baseaddr Size Sub Item ---------- ------------ ----- ------ 0x1000 0x800 (2 KB) No 'B' 0x3000 0xC00 (3 KB) No 'D' >>> print(c.get_overview()) Baseaddr Size Sub Item ---------- ------------ ----- ------ 0x2800 0x800 (2 KB) No 'C'
Cut nothing
>>> c = a.cut(0x2000, 0x100) >>> print(a.get_overview()) Baseaddr Size Sub Item ---------- ------------ ----- ------ 0x1000 0x800 (2 KB) No 'B' 0x3000 0xC00 (3 KB) No 'D' >>> print(c.get_overview()) Baseaddr Size Sub Item ---------- -------- ----- ------
- property decode_lsb: Optional[int]
Address decoding LSB (counted from 0).
>>> a = AddrMap() >>> a.decode_lsb is None True >>> a.add('A', 0x2000, '8 KB') AddrRange('A', 0x2000, '8 KB') >>> a.decode_lsb 13 >>> a.add('B', 0x5000, '1 KB') AddrRange('B', 0x5000, '1 KB') >>> a.decode_lsb 10 >>> a.add('C', 0x6000, '2 KB') AddrRange('C', 0x6000, '2 KB') >>> a.decode_lsb 10
- property decode_msb: Optional[int]
Address decoding MSB (counted from 0).
>>> a = AddrMap(addrwidth=32) >>> a.is_sub False >>> a.decode_msb 31 >>> a.add('A', 0x5000, '4 KB') AddrRange('A', 0x00005000, '4 KB', addrwidth=32) >>> a.decode_msb 31
>>> a = AddrMap(is_sub=True) >>> a.is_sub True >>> a.decode_msb is None True >>> a.add('A', 0x1000, '1 KB') AddrRange('A', 0x1000, '1 KB', is_sub=True) >>> a.decode_msb 12 >>> a.add('B', 0x2000, '8 KB') AddrRange('B', 0x2000, '8 KB', is_sub=True) >>> a.decode_msb 13 >>> a.add('C', 0x4000, 1) AddrRange('C', 0x4000, '1 byte', is_sub=True) >>> a.decode_msb 14
- property decode_slice
Address Slice.
>>> a = AddrMap() >>> a.decode_slice is None True >>> a.add('A', 0x1000, '4 KB') AddrRange('A', 0x1000, '4 KB') >>> a.decode_slice Slice('12') >>> a.add('B', 0x3000, '8 KB') AddrRange('B', 0x3000, '8 KB') >>> a.decode_slice Slice('14:12')
- property eff_addrwidth: Optional[int]
Effective Address Width.
Return address width, either explicitly set or calculated from existing entries.
>>> a = AddrMap() >>> a.eff_addrwidth >>> a.add('A', 0x5000, '4 KB') AddrRange('A', 0x5000, '4 KB') >>> a.eff_addrwidth 15 >>> a = AddrMap(addrwidth=16) >>> a.eff_addrwidth 16 >>> a.add('A', 2**18, '4 KB') Traceback (most recent call last): ... RuntimeError: AddrRange('A', 0x40000, '4 KB', addrwidth=16): exceeds maximum address range of 0x10000.
- find(item) AddrMap[source]
Return address map with address ranges containing item.
>>> a = AddrMap() >>> a.add('A', 0x5000, 0x1000) AddrRange('A', 0x5000, '4 KB') >>> a.add('B', 0x2000, 0x1000) AddrRange('B', 0x2000, '4 KB') >>> a.add('A', 0xD000, 0x800) AddrRange('A', 0xD000, '2 KB') >>> list(a.find('A')) [AddrRange('A', 0x5000, '4 KB'), AddrRange('A', 0xD000, '2 KB')]
- property firstaddr: Optional[int]
First used address.
>>> a = AddrMap() >>> a.firstaddr >>> a.add('A', 0x5000, '4 KB') AddrRange('A', 0x5000, '4 KB') >>> a.firstaddr Hex('0x5000') >>> a.add('B', 0x2000, '4 KB') AddrRange('B', 0x2000, '4 KB') >>> a.firstaddr Hex('0x2000')
- get(default=None)[source]
Return all
AddrRangeitems and fill gaps with default.>>> a = AddrMap() >>> a.add('T', size=0x400) AddrRange('T', 0x0, '1 KB') >>> a.add('A', 0x5000, 0x1000) AddrRange('A', 0x5000, '4 KB') >>> a.add('B', 0x2000, 0x1000) AddrRange('B', 0x2000, '4 KB') >>> a.add('C', 0xD000, '2 KB') AddrRange('C', 0xD000, '2 KB') >>> a.add('Z', size=0x2000) AddrRange('Z', 0xE000, '8 KB')
>>> for addrrange in a.get(): ... addrrange AddrRange('T', 0x0, '1 KB') AddrRange('B', 0x2000, '4 KB') AddrRange('A', 0x5000, '4 KB') AddrRange('C', 0xD000, '2 KB') AddrRange('Z', 0xE000, '8 KB')
>>> for addrrange in a.get(default='reserved'): ... addrrange AddrRange('T', 0x0, '1 KB') AddrRange('reserved', 0x400, '7 KB') AddrRange('B', 0x2000, '4 KB') AddrRange('reserved', 0x3000, '8 KB') AddrRange('A', 0x5000, '4 KB') AddrRange('reserved', 0x6000, '28 KB') AddrRange('C', 0xD000, '2 KB') AddrRange('reserved', 0xD800, '2 KB') AddrRange('Z', 0xE000, '8 KB')
Empty:
>>> a = AddrMap() >>> list(a.get()) [] >>> list(a.get(default="<default>")) [] >>> a = AddrMap(addrwidth=16) >>> list(a.get(default="<default>")) [AddrRange('<default>', 0x0000, '64 KB', addrwidth=16)]
Default items before and after real AddrRange:
>>> a.add('A', 0x5000, 0x1000) AddrRange('A', 0x5000, '4 KB', addrwidth=16) >>> for addrrange in a.get(default='reserved'): ... addrrange AddrRange('reserved', 0x0000, '20 KB', addrwidth=16) AddrRange('A', 0x5000, '4 KB', addrwidth=16) AddrRange('reserved', 0x6000, '40 KB', addrwidth=16)
>>> a.add('Z', 0xE000, size=0x2000) AddrRange('Z', 0xE000, '8 KB', addrwidth=16) >>> for addrrange in a.get(default='reserved'): ... addrrange AddrRange('reserved', 0x0000, '20 KB', addrwidth=16) AddrRange('A', 0x5000, '4 KB', addrwidth=16) AddrRange('reserved', 0x6000, '32 KB', addrwidth=16) AddrRange('Z', 0xE000, '8 KB', addrwidth=16)
- get_free_baseaddr(size: int, align=None, start=None) int[source]
Return baseaddress of free window with size.
- Parameters:
size – Window Size
- Keyword Arguments:
align – Alignment, default aligned to size
start – Start search behind given address
>>> a = AddrMap(is_sub=True, addrwidth=16) >>> a.get_free_baseaddr(0x10, start=0x0) Hex('0x0') >>> a.add('A', 0x1000, '1 KB') AddrRange('A', 0x1000, '1 KB', addrwidth=16, is_sub=True) >>> a.get_free_baseaddr(0x400) Hex('0x1400') >>> a.get_free_baseaddr('4 KB') Hex('0x2000') >>> a.get_free_baseaddr('8 KB', align=0x4000) Hex('0x4000') >>> a.get_free_baseaddr('1 KB', start=0x400) Hex('0x400') >>> a.get_free_baseaddr('1 KB', start=0x4000) Hex('0x4000') >>> a.add('B', 0x3000, '4 KB') AddrRange('B', 0x3000, '4 KB', addrwidth=16, is_sub=True) >>> a.get_free_baseaddr('4 KB', start=0x2800) Hex('0x4000')
If the AddrMap has addrwidth set, a check for end range overflow is executed
>>> a.get_free_baseaddr('8 KB', start=0xF0000) Traceback (most recent call last): ... ValueError: No space left in address map (64 KB) for new range at 0xF0000 with size of 8 KB >>> a.get_free_baseaddr('8 KB', align=0x1000, start=0xF000) Traceback (most recent call last): ... ValueError: No space left in address map (64 KB) for new range at 0xF000 with size of 8 KB
- get_overview() str[source]
Return overview table.
>>> a = AddrMap() >>> a.add('A', 0x5000, 0x1000) AddrRange('A', 0x5000, '4 KB') >>> a.add('B', 0x2000, 0x1000) AddrRange('B', 0x2000, '4 KB') >>> a.add('C', 0xD000, 0x800) AddrRange('C', 0xD000, '2 KB') >>> print(a.get_overview()) Baseaddr Size Sub Item ---------- ------------- ----- ------ 0x2000 0x1000 (4 KB) No 'B' 0x5000 0x1000 (4 KB) No 'A' 0xD000 0x800 (2 KB) No 'C'
- property is_full
Return if entire address map range is covered.
>>> a = AddrMap() >>> a.is_full is None True >>> a.add('A', size='8 KB') AddrRange('A', 0x0, '8 KB') >>> a.is_full True >>> a.add('B', size='4 KB') AddrRange('B', 0x2000, '4 KB') >>> a.is_full False >>> a.add('C', size='4 KB') AddrRange('C', 0x3000, '4 KB') >>> a.is_full True
>>> b = AddrMap(addrwidth=13) >>> b.is_full is None True >>> b.add('A', 0x0, size='6 KB') AddrRange('A', 0x0000, '6 KB', addrwidth=13) >>> b.is_full False >>> b.add('B', size='2 KB') AddrRange('B', 0x1800, '2 KB', addrwidth=13) >>> b.is_full True
- is_sub: bool
- property lastaddr: Optional[int]
Last used address.
- lookup(addr: int)[source]
Lookup address range by addr.
>>> a = AddrMap() >>> a.add('A', 0x5000, 0x1000) AddrRange('A', 0x5000, '4 KB') >>> a.add('B', 0x2000, 0x1000) AddrRange('B', 0x2000, '4 KB') >>> a.add('C', 0xD000, 0x800) AddrRange('C', 0xD000, '2 KB')
>>> a.lookup(0x2000) AddrRange('B', 0x2000, '4 KB') >>> a.lookup(0x2FFF) AddrRange('B', 0x2000, '4 KB') >>> a.lookup(0x3000)
- match(baseaddr: int, size: int = 1) AddrMap[source]
Return address map with address ranges intersecting with range from baseaddr for size.
>>> a = AddrMap() >>> a.add('A', 0x1000, 0x1000) AddrRange('A', 0x1000, '4 KB') >>> a.add('B', 0x2000, 0x1000) AddrRange('B', 0x2000, '4 KB') >>> a.add('C', 0x3000, 0x800) AddrRange('C', 0x3000, '2 KB') >>> m = a.match(0x1800, 0x1000) >>> m AddrMap() >>> list(m) [AddrRange('A', 0x1000, '4 KB'), AddrRange('B', 0x2000, '4 KB')]
- match_addrrange(addrrange: AddrRange) AddrMap[source]
Return address map with address ranges intersecting with range from baseaddr for size.
>>> a = AddrMap() >>> a.add('A', 0x1000, 0x1000) AddrRange('A', 0x1000, '4 KB') >>> a.add('B', 0x2000, 0x1000) AddrRange('B', 0x2000, '4 KB') >>> a.add('C', 0x3000, 0x800) AddrRange('C', 0x3000, '2 KB') >>> m = a.match_addrrange(AddrRange(0x1800, 0x1000)) >>> m AddrMap() >>> list(m) [AddrRange('A', 0x1000, '4 KB'), AddrRange('B', 0x2000, '4 KB')]