Skip to content

Commit 93c20e9

Browse files
povikmarcan
authored andcommitted
m1n1.hv: Allocate virtio resources if unspecified
Signed-off-by: Martin Povišer <[email protected]>
1 parent 020d86a commit 93c20e9

2 files changed

Lines changed: 50 additions & 2 deletions

File tree

proxyclient/m1n1/hv/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
from .gdbserver import *
1515
from .types import *
16+
from .virtutils import *
1617
from .virtio import *
1718

1819
__all__ = ["HV"]
@@ -1002,8 +1003,10 @@ def handle_bark(self, reason, code, info):
10021003
self.p.exit(0)
10031004

10041005
def attach_virtio(self, dev, base=None, irq=None, verbose=False):
1005-
assert base is not None and irq is not None
1006-
# TODO: ^-- allocate those if not chosen by caller
1006+
if base is None:
1007+
base = alloc_mmio_base(self.adt, 0x1000)
1008+
if irq is None:
1009+
irq = alloc_aic_irq(self.adt)
10071010

10081011
data = dev.config_data
10091012
data_base = self.u.heap.malloc(len(data))
@@ -1031,6 +1034,8 @@ def attach_virtio(self, dev, base=None, irq=None, verbose=False):
10311034
if name is None:
10321035
raise ValueError("Too many virtios in ADT")
10331036

1037+
print(f"Adding {n} @ 0x{base:x}, irq {irq}")
1038+
10341039
node = self.adt.create_node(name)
10351040
node.reg = [Container(addr=node.to_bus_addr(base), size=0x1000)]
10361041
node.interrupt_parent = getattr(self.adt["/arm-io/aic"], "AAPL,phandle")

proxyclient/m1n1/hv/virtutils.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# SPDX-License-Identifier: MIT
2+
from m1n1.utils import align_up
3+
4+
def collect_aic_irqs_in_use(adt):
5+
used = set()
6+
aic_phandle = getattr(adt["/arm-io/aic"], "AAPL,phandle")
7+
for node in adt.walk_tree():
8+
if not hasattr(node, "interrupt_parent") or \
9+
node.interrupt_parent != aic_phandle:
10+
continue
11+
for no in node.interrupts:
12+
used.add(no)
13+
return used
14+
15+
def usable_aic_irq_range(adt):
16+
# These are too optimistic but since we allocate
17+
# from the bottom of the range it doesn't matter much.
18+
return {
19+
"aic,1": range(0, 0x400),
20+
"aic,2": range(0, 0x1000),
21+
}.get(adt["/arm-io/aic"].compatible[0])
22+
23+
def alloc_aic_irq(adt):
24+
used = collect_aic_irqs_in_use(adt)
25+
for no in usable_aic_irq_range(adt):
26+
if no not in used:
27+
return no
28+
return None
29+
30+
def usable_mmio_range(adt):
31+
arm_io_range = adt["arm-io"].ranges[0]
32+
return range(arm_io_range.parent_addr, arm_io_range.parent_addr + arm_io_range.size)
33+
34+
def alloc_mmio_base(adt, size, alignment=0x4000):
35+
span = usable_mmio_range(adt)
36+
la = adt.build_addr_lookup()
37+
for zone, devs in la.populate(span):
38+
if len(devs) != 0:
39+
continue
40+
base = align_up(zone.start, alignment)
41+
if zone.stop > base + size:
42+
return base
43+
return None

0 commit comments

Comments
 (0)