Some comments of code are redundant, since the codes are
self-explanatory, so omit them.

Signed-off-by: Xuguo Wang <[email protected]>
---
 tools/jailhouse-config-create | 180 +++++++++++++++++++++++++++++++++---------
 1 file changed, 143 insertions(+), 37 deletions(-)

diff --git a/tools/jailhouse-config-create b/tools/jailhouse-config-create
index 4e61abc..9fe7f96 100755
--- a/tools/jailhouse-config-create
+++ b/tools/jailhouse-config-create
@@ -368,22 +368,30 @@ class PCIPCIBridge(PCIDevice):
         return (secondbus, subordinate)
 
 
-class MemRegion:
-    def __init__(self, start, stop, typestr, comments=None):
+class IORegion:
+    def __init__(self, start, stop, typestr):
         self.start = start
         self.stop = stop
         self.typestr = typestr
+
+
+# Each IOMemRegion represents one of the /proc/iomem entries.
+# It extends IORegion by the typestr property.
+class IOMemRegion(IORegion):
+    def __init__(self, start, stop, typestr, comments=None):
+
         if comments is None:
             self.comments = []
         else:
             self.comments = comments
+        IORegion.__init__(self, start, stop, typestr)
 
     def __str__(self):
-        return 'MemRegion: %08x-%08x : %s' % \
+        return 'IOMemRegion: %08x-%08x : %s' % \
             (self.start, self.stop, self.typestr)
 
     def size(self):
-        # round up to full PAGE_SIZE
+        # round up to PAGE_SIZE
         return int((self.stop - self.start + 0xfff) / 0x1000) * 0x1000
 
     def flagstr(self, p=''):
@@ -400,6 +408,19 @@ class MemRegion:
         return 'JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE'
 
 
+# Each IOPortRegion represents one of the /proc/ioports entries.
+# It extends IORegion typestr priority.
+# the value == 0 means permit, 1 means intercept.
+class IOPortRegion(IORegion):
+    def __init__(self, start, stop, typestr, value=0):
+        self.value = value
+        IORegion.__init__(self, start, stop, typestr)
+
+    def size(self):
+        # the range is from start to stop including self.start
+        return self.stop - self.start + 1
+
+
 class IOAPIC:
     def __init__(self, id, address, gsi_base, iommu=0, bdf=0):
         self.id = id
@@ -416,7 +437,11 @@ class IOAPIC:
         return (self.iommu << 16) | self.bdf
 
 
-class IOMemRegionTree:
+class IORegionTree:
+    # This regex matches entries in /proc/ioports, like
+    # '  0020-0021 : pic1'
+    IOEntry_Regex = re.compile('( *)([0-9a-f]*)-([0-9a-f]*) : (\w?.*)')
+
     def __init__(self, region, level):
         self.region = region
         self.level = level
@@ -434,6 +459,27 @@ class IOMemRegionTree:
             s += str(c)
         return s
 
+    @staticmethod
+    def parse_line(regionclass, line):
+        match = IORegionTree.IOEntry_Regex.match(line)
+        if not match:
+            raise ValueError('invalid entry')
+
+        # blank level
+        level = int(match.group(1).count(' ') / 2) + 1
+        # start address
+        start = match.group(2)
+        # end address
+        stop = match.group(3)
+        # comments
+        typestr = match.group(4)
+        return level, regionclass(int(start, 16), int(stop, 16), typestr)
+
+
+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,38 +503,30 @@ class IOMemRegionTree:
 
         # before Kernel if any
         if (r.start < kernel_start):
-            before_kernel = MemRegion(r.start, kernel_start - 1, s)
+            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):
-        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])
-
-    @staticmethod
     def parse_iomem_file():
         root = IOMemRegionTree(None, 0)
         f = input_open('/proc/iomem')
         lastlevel = 0
         lastnode = root
         for line in f:
-            (level, r) = IOMemRegionTree.parse_iomem_line(line)
+            level, r = IOMemRegionTree.parse_line(IOMemRegion, line)
             t = IOMemRegionTree(r, level)
-            if (t.level > lastlevel):
+            if t.level > lastlevel:
                 t.parent = lastnode
-            if (t.level == lastlevel):
+            if t.level == lastlevel:
                 t.parent = lastnode.parent
-            if (t.level < lastlevel):
+            if t.level < lastlevel:
                 p = lastnode.parent
                 while(t.level < p.level):
                     p = p.parent
@@ -510,11 +548,11 @@ class IOMemRegionTree:
             r = tree.region
             s = r.typestr
 
-            if (s.find('HPET') >= 0):
+            if s.find('HPET') >= 0:
                 regions.append(r)
 
             # if the tree continues recurse further down ...
-            if (len(tree.children) > 0):
+            if len(tree.children) > 0:
                 regions.extend(IOMemRegionTree.find_hpet_regions(tree))
 
         return regions
@@ -543,12 +581,12 @@ class IOMemRegionTree:
                 continue
 
             # generally blacklisted, unless we find an HPET behind it
-            if (s == 'reserved'):
+            if s == 'reserved':
                 regions.extend(IOMemRegionTree.find_hpet_regions(tree))
                 continue
 
             # if the tree continues recurse further down ...
-            if (len(tree.children) > 0):
+            if len(tree.children) > 0:
                 regions.extend(IOMemRegionTree.parse_iomem_tree(tree))
                 continue
 
@@ -558,6 +596,72 @@ class IOMemRegionTree:
         return regions
 
 
+class IOPortRegionTree(IORegionTree):
+    def __init__(self, region, level):
+        IORegionTree.__init__(self, region, level)
+
+    @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_line(IOPortRegion, 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
+            c = r.typestr
+
+            # intercept keyboard and PCI conf1
+            if (c is not None and (c == 'keyboard' or c == 'PCI conf1')):
+                r.value = IOPortRegionTree.get_first_ioport_byte(
+                            r.start, r.stop)
+
+            # 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
+
+    # get a byte of ioport region mask from start_permitted, end
+    # at the last_permitted bit.
+    @staticmethod
+    def get_first_ioport_byte(start_permitted, last_permitted):
+        byte_head = start_permitted % 8
+        byte_tail = last_permitted % 8
+        byte = (1 << byte_head) - 1
+        byte |= (~((1 << (byte_tail + 1)) - 1) & 0xff)
+        byte &= 0xff
+        return int(byte)
+
+
 class IOMMUConfig(object):
     def __init__(self, props):
         self.base_addr = props['base_addr']
@@ -577,7 +681,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 +692,12 @@ 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 +771,12 @@ 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 +931,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 +1108,8 @@ 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 +1241,9 @@ 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

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to