mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-25 16:10:16 +00:00
m1n1.hv: Allocate virtio resources if unspecified
Signed-off-by: Martin Povišer <povik@cutebit.org>
This commit is contained in:
parent
020d86a23f
commit
93c20e9395
2 changed files with 50 additions and 2 deletions
|
@ -13,6 +13,7 @@ from .. import xnutools, shell
|
||||||
|
|
||||||
from .gdbserver import *
|
from .gdbserver import *
|
||||||
from .types import *
|
from .types import *
|
||||||
|
from .virtutils import *
|
||||||
from .virtio import *
|
from .virtio import *
|
||||||
|
|
||||||
__all__ = ["HV"]
|
__all__ = ["HV"]
|
||||||
|
@ -1002,8 +1003,10 @@ class HV(Reloadable):
|
||||||
self.p.exit(0)
|
self.p.exit(0)
|
||||||
|
|
||||||
def attach_virtio(self, dev, base=None, irq=None, verbose=False):
|
def attach_virtio(self, dev, base=None, irq=None, verbose=False):
|
||||||
assert base is not None and irq is not None
|
if base is None:
|
||||||
# TODO: ^-- allocate those if not chosen by caller
|
base = alloc_mmio_base(self.adt, 0x1000)
|
||||||
|
if irq is None:
|
||||||
|
irq = alloc_aic_irq(self.adt)
|
||||||
|
|
||||||
data = dev.config_data
|
data = dev.config_data
|
||||||
data_base = self.u.heap.malloc(len(data))
|
data_base = self.u.heap.malloc(len(data))
|
||||||
|
@ -1031,6 +1034,8 @@ class HV(Reloadable):
|
||||||
if name is None:
|
if name is None:
|
||||||
raise ValueError("Too many virtios in ADT")
|
raise ValueError("Too many virtios in ADT")
|
||||||
|
|
||||||
|
print(f"Adding {n} @ 0x{base:x}, irq {irq}")
|
||||||
|
|
||||||
node = self.adt.create_node(name)
|
node = self.adt.create_node(name)
|
||||||
node.reg = [Container(addr=node.to_bus_addr(base), size=0x1000)]
|
node.reg = [Container(addr=node.to_bus_addr(base), size=0x1000)]
|
||||||
node.interrupt_parent = getattr(self.adt["/arm-io/aic"], "AAPL,phandle")
|
node.interrupt_parent = getattr(self.adt["/arm-io/aic"], "AAPL,phandle")
|
||||||
|
|
43
proxyclient/m1n1/hv/virtutils.py
Normal file
43
proxyclient/m1n1/hv/virtutils.py
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
from m1n1.utils import align_up
|
||||||
|
|
||||||
|
def collect_aic_irqs_in_use(adt):
|
||||||
|
used = set()
|
||||||
|
aic_phandle = getattr(adt["/arm-io/aic"], "AAPL,phandle")
|
||||||
|
for node in adt.walk_tree():
|
||||||
|
if not hasattr(node, "interrupt_parent") or \
|
||||||
|
node.interrupt_parent != aic_phandle:
|
||||||
|
continue
|
||||||
|
for no in node.interrupts:
|
||||||
|
used.add(no)
|
||||||
|
return used
|
||||||
|
|
||||||
|
def usable_aic_irq_range(adt):
|
||||||
|
# These are too optimistic but since we allocate
|
||||||
|
# from the bottom of the range it doesn't matter much.
|
||||||
|
return {
|
||||||
|
"aic,1": range(0, 0x400),
|
||||||
|
"aic,2": range(0, 0x1000),
|
||||||
|
}.get(adt["/arm-io/aic"].compatible[0])
|
||||||
|
|
||||||
|
def alloc_aic_irq(adt):
|
||||||
|
used = collect_aic_irqs_in_use(adt)
|
||||||
|
for no in usable_aic_irq_range(adt):
|
||||||
|
if no not in used:
|
||||||
|
return no
|
||||||
|
return None
|
||||||
|
|
||||||
|
def usable_mmio_range(adt):
|
||||||
|
arm_io_range = adt["arm-io"].ranges[0]
|
||||||
|
return range(arm_io_range.parent_addr, arm_io_range.parent_addr + arm_io_range.size)
|
||||||
|
|
||||||
|
def alloc_mmio_base(adt, size, alignment=0x4000):
|
||||||
|
span = usable_mmio_range(adt)
|
||||||
|
la = adt.build_addr_lookup()
|
||||||
|
for zone, devs in la.populate(span):
|
||||||
|
if len(devs) != 0:
|
||||||
|
continue
|
||||||
|
base = align_up(zone.start, alignment)
|
||||||
|
if zone.stop > base + size:
|
||||||
|
return base
|
||||||
|
return None
|
Loading…
Reference in a new issue