Address Map
Address Map.
Classes:
| Name | Description |
|---|---|
AddrMap |
Address Map. |
Conflict |
AddrMap Conflict Error. |
AddrMap
Address Map.
Other Parameters:
| Name | Type | Description |
|---|---|---|
addrwidth |
int
|
Address width. Calculated automatically. |
is_sub |
bool
|
Handle sub addresses only. Just the minimum number of address bits is evaluated. |
# |
default (object
|
Default item, returned on unallocated address ranges. |
allow_overlapping |
bool
|
Allow overlapping address ranges. |
Example:
>>> 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 :class:AddrRange objects 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 number 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, '3940292 KB')
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 attribute 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')
Methods:
| Name | Description |
|---|---|
cp_addrranges |
Copy address ranges from |
add |
Add |
get_free_baseaddr |
Return baseaddress of free window with |
get |
Return all :any: |
cut |
Cut out address range from |
lookup |
Lookup address range by |
match |
Return address map with address ranges intersecting with range from |
match_addrrange |
Return address map with address ranges intersecting with range from |
find |
Return address map with address ranges containing |
get_overview |
Return overview table. |
Attributes:
| Name | Type | Description |
|---|---|---|
firstaddr |
int | None
|
First used address. |
lastaddr |
int | None
|
Last used address. |
addrspace |
int | None
|
Allocated Address space. |
eff_addrwidth |
int | None
|
Effective Address Width. |
decode_lsb |
int | None
|
Address decoding LSB (counted from 0). |
decode_msb |
int | None
|
Address decoding MSB (counted from 0). |
decode_slice |
Address Slice. |
|
is_full |
Return if entire address map range is covered. |
firstaddr
property
First used address.
Example:
>>> 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')
addrspace
property
Allocated Address space.
Example:
>>> 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'
eff_addrwidth
property
Effective Address Width.
Return address width, either explicitly set or calculated from existing entries.
Example:
>>> 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.
decode_lsb
property
Address decoding LSB (counted from 0).
Example:
>>> 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
decode_msb
property
Address decoding MSB (counted from 0).
Example:
>>> 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
decode_slice
property
Address Slice.
Example:
>>> 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')
is_full
property
Return if entire address map range is covered.
Example:
>>> 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
add
Add item for address decoding.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item
|
any object managed by this address decoder |
required |
Other Parameters:
| Name | Type | Description |
|---|---|---|
baseaddr |
int | None
|
Base address. Behind last item by default. |
size |
int
|
Size in bytes |
is_sub |
bool | None
|
Overwrite sub address attribute. |
align |
int | None
|
Alignment |
startsearch |
int | None
|
Search of free address at given number (if |
Example:
>>> 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')
get_free_baseaddr
Return baseaddress of free window with size.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
size
|
int
|
Window Size |
required |
Other Parameters:
| Name | Type | Description |
|---|---|---|
align |
Alignment, default aligned to size |
|
start |
Start search behind given address |
Example:
>>> 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
Return all :any:AddrRange items and fill gaps with default.
Example:
>>> 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)
cut
Cut out address range from baseaddr for size.
Return address map with cut address ranges.
Example:
>>> 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
---------- -------- ----- ------
lookup
Lookup address range by addr.
Example:
>>> 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
Return address map with address ranges intersecting with range from baseaddr for size.
Example:
>>> 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
Return address map with address ranges intersecting with range from baseaddr for size.
Example:
>>> 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')]
find
Return address map with address ranges containing item.
Example:
>>> 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')]
get_overview
Return overview table.
Example:
>>> 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'