Abstract the common property of the MemRegion and PortRegion
to the super class IORegion, named IOMemRegion and IOPortRegion
for parsing the /proc/ioports, the same action of the MemRegion-
Tree.
Signed-off-by: Xuguo Wang <
hudd...@gmail.com>
---
tools/jailhouse-config-create | 187 ++++++++++++++++++++++++++++++++++++------
1 file changed, 161 insertions(+), 26 deletions(-)
diff --git a/tools/jailhouse-config-create b/tools/jailhouse-config-create
index 4e61abc..9c6cf57 100755
--- a/tools/jailhouse-config-create
+++ b/tools/jailhouse-config-create
@@ -368,18 +368,31 @@ class PCIPCIBridge(PCIDevice):
return (secondbus, subordinate)
-class MemRegion:
- def __init__(self, start, stop, typestr, comments=None):
+# super class of IOMemRegion and IOPortRegion
+class IORegion:
+ def __init__(self, start, stop, comments=None):
self.start = start
self.stop = stop
- self.typestr = typestr
+
if comments is None:
self.comments = []
else:
self.comments = comments
def __str__(self):
- return 'MemRegion: %08x-%08x : %s' % \
+ return 'IORegion: %08x-%08x : %s' % \
+ (self.start, self.stop, self.comments)
+
+
+# IOMemRegion includes the one of the /proc/iomem entry.
+# IOMemRegion has his special priority typestr.
+class IOMemRegion(IORegion):
+ def __init__(self, start, stop, typestr, comments=None):
+ self.typestr = typestr
+ IORegion.__init__(self, start, stop, comments)
+
+ def __str__(self):
+ return 'IOMemRegion: %08x-%08x : %s' % \
(self.start, self.stop, self.typestr)
def size(self):
@@ -400,6 +413,18 @@ class MemRegion:
return 'JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE'
+# IOPortRegion includes one of the /proc/ioports entry.
+# IOPortRegion has his special priority value.
+class IOPortRegion(IORegion):
+ def __init__(self, start, stop, value, comments=None):
+ self.value = value
+ IORegion.__init__(self, start, stop, comments)
+
+ def size(self):
+ # plus 1 more for len since the self.start start from 0
+ return int(self.stop - self.start) + 1
+
+
class IOAPIC:
def __init__(self, id, address, gsi_base, iommu=0, bdf=0):
self.id = id
@@ -416,7 +441,8 @@ class IOAPIC:
return (self.iommu << 16) | self.bdf
-class IOMemRegionTree:
+# super class of IOMemRegionTree and IOPortRegionTree
+class IORegionTree:
def __init__(self, region, level):
self.region = region
self.level = level
@@ -425,15 +451,24 @@ class IOMemRegionTree:
def __str__(self):
s = ''
- if (self.region):
+ if (self):
s = (' ' * (self.level - 1)) + str(self.region)
if self.parent and self.parent.region:
- s += ' --> ' + self.parent.region.typestr
+ if hasattr(self.parent.region, 'typestr'):
+ s += ' --> ' + self.parent.region.typestr
+ else:
+ s += ' --> ' + self.parent.region.comments
s += '\n'
for c in self.children:
s += str(c)
return s
+
+# parse the IOMemRegions to the tree structure.
+class IOMemRegionTree(IORegionTree):
+ def __init__(self, region, level):
+ IORegionTree.__init__(self, region, level)
+
def regions_split_by_kernel(self):
kernel = [x for x in self.children if
x.region.typestr.startswith('Kernel ')]
@@ -457,23 +492,24 @@ class IOMemRegionTree:
# before Kernel if any
if (r.start < kernel_start):
- before_kernel = MemRegion(r.start, kernel_start - 1, s)
+ # only the IOMemRegion should split the kernel
+ before_kernel = IOMemRegion(r.start, kernel_start - 1, s)
- kernel_region = MemRegion(kernel_start, kernel_stop, "Kernel")
+ kernel_region = IOMemRegion(kernel_start, kernel_stop, "Kernel")
# after Kernel if any
if (r.stop > kernel_stop):
- after_kernel = MemRegion(kernel_stop + 1, r.stop, s)
+ after_kernel = IOMemRegion(kernel_stop + 1, r.stop, s)
return [before_kernel, kernel_region, after_kernel]
@staticmethod
- def parse_iomem_line(line):
+ def parse_ioregion_line(line):
a = line.split(':', 1)
level = int(a[0].count(' ') / 2) + 1
region = a[0].split('-', 1)
a[1] = a[1].strip()
- return level, MemRegion(int(region[0], 16), int(region[1], 16), a[1])
+ return level, IOMemRegion(int(region[0], 16), int(region[1], 16), a[1])
@staticmethod
def parse_iomem_file():
@@ -482,7 +518,7 @@ class IOMemRegionTree:
lastlevel = 0
lastnode = root
for line in f:
- (level, r) = IOMemRegionTree.parse_iomem_line(line)
+ (level, r) = IOMemRegionTree.parse_ioregion_line(line)
t = IOMemRegionTree(r, level)
if (t.level > lastlevel):
t.parent = lastnode
@@ -558,6 +594,97 @@ class IOMemRegionTree:
return regions
+# parse the IOPortRegion to the tree structure.
+class IOPortRegionTree(IORegionTree):
+ def __init__(self, region, level):
+ IORegionTree.__init__(self, region, level)
+
+ @staticmethod
+ def parse_ioregion_line(line):
+ a = line.split(':', 1)
+ level = int(a[0].count(' ') / 2) + 1
+ region = a[0].split('-', 1)
+ a[1] = a[1].strip()
+ return level, IOPortRegion(
+ int(region[0], 16), int(region[1], 16), 0, a[1])
+
+ @staticmethod
+ def parse_ioport_file():
+ root = IOPortRegionTree(None, 0)
+ f = input_open('/proc/ioports')
+ lastlevel = 0
+ lastnode = root
+ for line in f:
+ (level, r) = IOPortRegionTree.parse_ioregion_line(line)
+ t = IOPortRegionTree(r, level)
+ if (t.level > lastlevel):
+ t.parent = lastnode
+ if (t.level == lastlevel):
+ t.parent = lastnode.parent
+ if (t.level < lastlevel):
+ p = lastnode.parent
+ while(t.level < p.level):
+ p = p.parent
+ t.parent = p.parent
+
+ t.parent.children.append(t)
+ lastnode = t
+ lastlevel = t.level
+ f.close()
+
+ return root
+
+ # recurse down the tree
+ @staticmethod
+ def parse_ioport_tree(tree):
+ regions = []
+
+ for tree in tree.children:
+ r = tree.region
+ s = r.value
+ c = r.comments
+
+ # set keyboard and PCI conf1 disable, others enable
+ if (c is not None and (c == 'keyboard' or c == 'PCI conf1')):
+ r.value = IOPortRegionTree.parse_ioport_value(
+ r.start, r.stop + 1)
+
+ # if the tree continues recurse further down ...
+ if (len(tree.children) > 0):
+ regions.extend(IOPortRegionTree.parse_ioport_tree(tree))
+ continue
+
+ # add all remaining leaves
+ regions.append(r)
+
+ return regions
+
+ @staticmethod
+ def parse_ioport_value(start, stop):
+ size = stop - start
+ value = -1
+ if size > 8:
+ value = -1
+ elif size == 8:
+ value = 0xff
+ elif size == 7:
+ value = 0x7f
+ elif size == 6:
+ value = 0x3f
+ elif size == 5:
+ value = 0x1f
+ elif size == 4:
+ value = 0x0f
+ elif size == 3:
+ value = 0x07
+ elif size == 2:
+ value = 0x03
+ else:
+ value = 0x01
+
+ return value
+
+
class IOMMUConfig(object):
def __init__(self, props):
self.base_addr = props['base_addr']
@@ -577,7 +704,7 @@ def parse_iomem(pcidevices):
regions = IOMemRegionTree.parse_iomem_tree(
IOMemRegionTree.parse_iomem_file())
- rom_region = MemRegion(0xc0000, 0xdffff, 'ROMs')
+ rom_region = IOMemRegion(0xc0000, 0xdffff, 'ROMs')
add_rom_region = False
ret = []
@@ -588,12 +715,14 @@ def parse_iomem(pcidevices):
for d in pcidevices:
if d.msix_address >= r.start and d.msix_address <= r.stop:
if d.msix_address > r.start:
- head_r = MemRegion(r.start, d.msix_address - 1,
- r.typestr, r.comments)
+ head_r = IOMemRegion(
+ r.start, d.msix_address - 1,
+ r.typestr, r.comments)
ret.append(head_r)
if d.msix_address + d.msix_region_size < r.stop:
- tail_r = MemRegion(d.msix_address + d.msix_region_size,
- r.stop, r.typestr, r.comments)
+ tail_r = IOMemRegion(
+ d.msix_address + d.msix_region_size,
+ r.stop, r.typestr, r.comments)
ret.append(tail_r)
append_r = False
break
@@ -667,11 +796,14 @@ def alloc_mem(regions, size):
r.stop + 1 >= mem[0] + mem[1]
):
if r.start < mem[0]:
- head_r = MemRegion(r.start, mem[0] - 1, r.typestr, r.comments)
+ head_r = IOMemRegion(
+ r.start, mem[0] - 1,
+ r.typestr, r.comments)
regions.insert(regions.index(r), head_r)
if r.stop + 1 > mem[0] + mem[1]:
- tail_r = MemRegion(mem[0] + mem[1], r.stop, r.typestr,
- r.comments)
+ tail_r = IOMemRegion(
+ mem[0] + mem[1], r.stop,
+ r.typestr, r.comments)
regions.insert(regions.index(r), tail_r)
regions.remove(r)
return mem
@@ -826,7 +958,7 @@ def parse_dmar(pcidevices, ioapics, dmar_regions):
comments.append('DMAR parser could not decode device path')
offset += scope_len
- reg = MemRegion(base, limit, 'ACPI DMAR RMRR', comments)
+ reg = IOMemRegion(base, limit, 'ACPI DMAR RMRR', comments)
regions.append(reg)
f.seek(struct_len - offset, os.SEEK_CUR)
@@ -1003,7 +1135,9 @@ def parse_ivrs(pcidevices, ioapics):
'regions. The memory at 0x%x will be mapped accessible '
'to all devices.' % mem_addr)
- regions.append(MemRegion(mem_addr, mem_len, 'ACPI IVRS', comment))
+ regions.append(IOMemRegion(
+ mem_addr, mem_len,
+ 'ACPI IVRS', comment))
elif type == 0x40:
raise RuntimeError(
'You board uses IVRS Rev. 2 feature Jailhouse doesn\'t '
@@ -1135,9 +1269,10 @@ elif (total > ourmem[1]):
hvmem[0] = ourmem[0]
-inmatereg = MemRegion(ourmem[0] + hvmem[1],
- ourmem[0] + hvmem[1] + inmatemem - 1,
- 'JAILHOUSE Inmate Memory')
+inmatereg = IOMemRegion(
+ ourmem[0] + hvmem[1],
+ ourmem[0] + hvmem[1] + inmatemem - 1,
+ 'JAILHOUSE Inmate Memory')
regions.append(inmatereg)
cpucount = count_cpus()
--
2.5.0