Refactoring the algorithm to the generate the .pio_bitmap using
the ioports entries and new parameters for the
root-cell-config.c-tmpl.

Signed-off-by: Xuguo Wang <[email protected]>

This is the PATCH V4, some whitespaces added after the comma.
---
 tools/jailhouse-config-create | 307 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 298 insertions(+), 9 deletions(-)

diff --git a/tools/jailhouse-config-create b/tools/jailhouse-config-create
index 727c87f..e43e7ec 100755
--- a/tools/jailhouse-config-create
+++ b/tools/jailhouse-config-create
@@ -1133,15 +1133,301 @@ def parse_ivrs(pcidevices, ioapics):
         return units, regions
 
 
+# parse the /proc/ioports
 def parse_ioports():
     pm_timer_base = None
-    f = input_open('/proc/ioports')
-    for line in f:
-        if line.endswith('ACPI PM_TMR\n'):
-            pm_timer_base = int(line.split('-')[0], 16)
-            break
-    f.close()
-    return pm_timer_base
+    bitmap_regions = []
+    regions = IOPortRegionTree.parse_ioport_tree(
+            IOPortRegionTree.parse_ioport_file())
+
+    for region in regions:
+        # parse the ACPI PM_TMR
+        if region.typestr == 'ACPI PM_TMR':
+            pm_timer_base = region.start
+            continue
+
+        # region PCI conf1 must intercept
+        if region.typestr == 'PCI conf1':
+            region.value = 0xff
+            if region.size() > 8:
+                region.value = -1
+            bitmap_regions.append(region)
+            continue
+
+        # region in bytes
+        byte_size = region.size()/8
+
+        # head and tail are not aligned
+        if region.start % 8 != 0 and (region.stop % 8 + 1) % 8 != 0:
+            # direct to the decrease
+            round_up = (region.start % 8)
+            # direct to the increase
+            round_down = 7 - (region.stop % 8)
+
+            # region has one byte
+            if byte_size <= 1:
+                value = IOPortRegionTree.get_first_ioport_byte(region.start,
+                                                               region.stop)
+                region.start -= round_up
+                region.stop += round_down
+
+                # overlap with the valuable region
+                if region.start - round_up < bitmap_regions[-1].stop:
+                    region.value = bitmap_regions[-1].value & value
+                    region.typestr += ', ' + bitmap_regions[-1].typestr
+                    bitmap_regions.pop()
+                else:
+                    region.value = value
+                bitmap_regions.append(region)
+
+            # region has two bytes
+            elif byte_size <= 2:
+                value_head = IOPortRegionTree.get_first_ioport_byte(
+                                region.start, region.start + (7 - round_up))
+                value_tail = IOPortRegionTree.get_first_ioport_byte(
+                                region.stop - (region.stop % 8), region.stop)
+                region.start -= round_up
+                region.stop += round_down
+
+                # overlap with the valid region
+                if region.start - round_up < bitmap_regions[-1].stop:
+                    region.value = bitmap_regions[-1].value & value_head
+                    region.typestr += ', ' + bitmap_regions[-1].typestr
+                    bitmap_regions.pop()
+                    bitmap_regions.append(IOPortRegion(
+                                            region.start,
+                                            region.start + (7 - round_up),
+                                            region.typestr, region.value))
+                    bitmap_regions.append(IOPortRegion(
+                                            region.stop - (region.stop % 8),
+                                            region.stop,
+                                            region.typestr,
+                                            value_tail))
+                else:
+                    region.value = value_head
+                    bitmap_regions.append(IOPortRegion(
+                                            region.start,
+                                            region.start + (7 - round_up),
+                                            region.typestr,
+                                            region.value))
+                    bitmap_regions.append(IOPortRegion(
+                                            region.stop - (region.stop % 8),
+                                            region.stop,
+                                            region.typestr,
+                                            value_tail))
+
+            # region is large than two bytes
+            else:
+                value_head = IOPortRegionTree.get_first_ioport_byte(
+                                region.start, region.start + (7 - round_up))
+                value_tail = IOPortRegionTree.get_first_ioport_byte(
+                                region.stop - (region.stop % 8), region.stop)
+                region.start -= round_up
+                region.stop += round_down
+
+                # overlap with the valid region
+                if region.start - round_up < bitmap_regions[-1].stop:
+                    region.value = bitmap_regions[-1].value & value_head
+                    region.typestr += ', ' + bitmap_regions[-1].typestr
+                    bitmap_regions.pop()
+                    bitmap_regions.append(IOPortRegion(
+                                            region.start,
+                                            region.start + (7 - round_up),
+                                            region.typestr,
+                                            region.value))
+                    bitmap_regions.append(IOPortRegion(
+                                            region.stop - (region.stop % 8),
+                                            region.stop,
+                                            region.typestr,
+                                            value_tail))
+                else:
+                    region.value = value_head
+                    bitmap_regions.append(IOPortRegion(
+                                            region.start,
+                                            region.start + (7 - round_up),
+                                            region.typestr,
+                                            region.value))
+                    bitmap_regions.append(IOPortRegion(
+                                           region.start + (7 - round_up) + 1,
+                                           region.stop - (region.stop % 8) - 1,
+                                           region.typestr,
+                                           0))
+                    bitmap_regions.append(IOPortRegion(
+                                            region.stop - (region.stop % 8),
+                                            region.stop,
+                                            region.typestr,
+                                            value_tail))
+
+        # head not aligned but tail aligned
+        elif region.start % 8 != 0 \
+                and (region.stop % 8 + 1) % 8 == 0:
+            round_up = (region.start % 8)
+
+            # region has one byte
+            if byte_size <= 1:
+                value = IOPortRegionTree.get_first_ioport_byte(
+                            region.start, region.stop)
+                region.start -= round_up
+
+                # overlap the valid region
+                if region.start - round_up < bitmap_regions[-1].stop:
+                    region.value = bitmap_regions[-1].value & value
+                    region.typestr += ', ' + bitmap_regions[-1].typestr
+                    bitmap_regions.pop()
+                else:
+                    region.value = value
+
+                bitmap_regions.append(region)
+
+            # region has two bytes
+            elif byte_size <= 2:
+                value_head = IOPortRegionTree.get_first_ioport_byte(
+                                region.start, region.start + (7 - round_up))
+                value_tail = IOPortRegionTree.get_first_ioport_byte(
+                                region.stop - (region.stop % 8), region.stop)
+                region.start -= round_up
+
+                # overlap the valid region
+                if region.start - round_up < bitmap_regions[-1].stop:
+                    region.value = bitmap_regions[-1].value & value_head
+                    region.typestr += ', ' + bitmap_regions[-1].typestr
+                    bitmap_regions.pop()
+                    bitmap_regions.append(IOPortRegion(
+                                            region.start,
+                                            region.start + (7 - round_up),
+                                            region.typestr,
+                                            region.value))
+                    bitmap_regions.append(IOPortRegion(
+                                            region.stop - (region.stop % 8),
+                                            region.stop,
+                                            region.typestr,
+                                            value_tail))
+                else:
+                    region.value = value_head
+                    bitmap_regions.append(IOPortRegion(
+                                            region.start,
+                                            region.start + (7 - round_up),
+                                            region.typestr,
+                                            region.value))
+                    bitmap_regions.append(IOPortRegion(
+                                            region.stop - (region.stop % 8),
+                                            region.stop,
+                                            region.typestr,
+                                            value_tail))
+
+            # region has more than two bytes
+            else:
+                value_head = IOPortRegionTree.get_first_ioport_byte(
+                                region.start, region.start + (7 - round_up))
+                value_tail = IOPortRegionTree.get_first_ioport_byte(
+                                region.stop - (region.stop % 8), region.stop)
+                region.start -= round_up
+
+                # overlap with valid region
+                if region.start - round_up < bitmap_regions[-1].stop:
+                    region.value = bitmap_regions[-1].value & value_head
+                    region.typestr += ', ' + bitmap_regions[-1].typestr
+                    bitmap_regions.pop()
+                    bitmap_regions.append(IOPortRegion(
+                                            region.start,
+                                            region.start + (7 - round_up),
+                                            region.typestr,
+                                            region.value))
+                    bitmap_regions.append(IOPortRegion(
+                                            region.stop - (region.stop % 8),
+                                            region.stop,
+                                            region.typestr,
+                                            value_tail))
+                else:
+                    bitmap_regions.append(IOPortRegion(
+                                            region.start,
+                                            region.start + (7 - round_up),
+                                            region.typestr,
+                                            value_head))
+                    bitmap_regions.append(IOPortRegion(
+                                            region.start + (7 - round_up) + 1,
+                                            region.stop,
+                                            region.typestr,
+                                            0))
+
+        # head aligned but not tail
+        elif region.start % 8 == 0 \
+                and (region.stop % 8 + 1) % 8 != 0:
+            round_down = 7 - (region.stop % 8)
+
+            # region has only one byte
+            if byte_size <= 1:
+                value = IOPortRegionTree.get_first_ioport_byte(
+                            region.start, region.stop)
+                region.stop += round_down
+                region.value = value
+                bitmap_regions.append(region)
+
+            # region has two bytes
+            elif byte_size <= 2:
+                value_tail = IOPortRegionTree.get_first_ioport_byte(
+                                region.stop - (region.stop % 8), region.stop)
+                region.stop += round_down
+                bitmap_regions.append(IOPortRegion(
+                                        region.start,
+                                        region.start + 7,
+                                        region.typestr,
+                                        0))
+                bitmap_regions.append(IOPortRegion(
+                                        region.stop - (region.stop % 8),
+                                        region.stop,
+                                        region.typestr,
+                                        value_tail))
+
+            # region has more then two bytes
+            else:
+                value_tail = IOPortRegionTree.get_first_ioport_byte(
+                                region.stop - (region.stop % 8), region.stop)
+                region.stop += round_down
+                bitmap_regions.append(IOPortRegion(
+                                        region.start,
+                                        region.stop - (region.stop % 8) - 1,
+                                        region.typestr,
+                                        0))
+                bitmap_regions.append(IOPortRegion(
+                                        region.stop - (region.stop % 8),
+                                        region.stop,
+                                        region.typestr,
+                                        value_tail))
+
+        # head and tail are all aligned
+        else:
+            region.value = 0
+            bitmap_regions.append(region)
+
+    # replenishment the region
+    for region in bitmap_regions:
+        i = bitmap_regions.index(region)
+        if region.start != 0 \
+                and region.stop != 0xffff \
+                and region != bitmap_regions[-1]:
+            if region.stop + 1 != bitmap_regions[i + 1].start:
+                size = bitmap_regions[i + 1].start - region.stop - 1
+                value = 0xff
+                if size > 8:
+                    value = -1
+                bitmap_regions.insert(i + 1,
+                                      IOPortRegion(
+                                        region.stop + 1,
+                                        bitmap_regions[i + 1].start - 1,
+                                        '',
+                                        value))
+
+    # pad with the 0xff if the last address is not 0xffff
+    if bitmap_regions[-1].stop != 0xffff:
+        start = bitmap_regions[-1].stop + 1
+        stop = 0xffff
+        value = 0xff
+        if stop - start - 1 > 8:
+            value = -1
+        bitmap_regions.append(IOPortRegion(start, stop, '', value))
+
+    return pm_timer_base, bitmap_regions
 
 
 class MMConfig:
@@ -1251,7 +1537,8 @@ regions.append(inmatereg)
 
 cpucount = count_cpus()
 
-pm_timer_base = parse_ioports()
+(pm_timer_base, pm_bitmap_regions) = parse_ioports()
+pm_bitmap_size = int(pm_bitmap_regions[-1].stop/8 + 1)
 
 
 f = open(options.file, 'w')
@@ -1269,7 +1556,9 @@ kwargs = {
     'irqchips': ioapics,
     'pm_timer_base': pm_timer_base,
     'mmconfig': mmconfig,
-    'iommu_units': iommu_units
+    'iommu_units': iommu_units,
+    'pm_bitmap_size': pm_bitmap_size,
+    'pm_bitmap_regions': pm_bitmap_regions
 }
 
 f.write(tmpl.render(**kwargs))
-- 
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