Refactoring the algorithm to the generate the .pio_bitmap using
the ioports entries and new parameters for the
root-cell-config.c-tmpl.
v7:
- fix the merge conflicts.
v6:
- refactor the static function of parse_ioport_tree to non-static
- refactor the function of parse_ioport
- add the docstring to the function of parse_ioport
Signed-off-by: Xuguo Wang <[email protected]>
---
tools/jailhouse-config-create | 176 +++++++++++++++++++++++++++++++++++++++---
1 file changed, 167 insertions(+), 9 deletions(-)
diff --git a/tools/jailhouse-config-create b/tools/jailhouse-config-create
index 348de60..f2928bd 100755
--- a/tools/jailhouse-config-create
+++ b/tools/jailhouse-config-create
@@ -1341,14 +1341,169 @@ def parse_ivrs(pcidevices, ioapics):
def parse_ioports():
+ """
+ This function parses the file content of /proc/ioports to the data
formatted
+ of pio_bitmap need.
+
+ - return type :
+ long: base address of pm_timer_base
+ list: contains all /proc/ioports entries
+ - return value :
+ pm_timer_base: the base address of pm_timer_base
+ bitmap_regions: pio_bitmap list
+ - example :
+ (pm_timer_base, pm_bitmap_regions) = 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_file().parse_ioport_tree()
+
+ 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
+
+ byte_size = region.size() / 8
+
+ # alignment spefication
+ both_aligned = 0
+ both_not_aligned = 1
+ tail_aligned = 2
+ head_aligned = 3
+
+ alignment = region.alignment()
+
+ if alignment == both_aligned:
+ region.value = 0
+ bitmap_regions.append(region)
+ continue
+
+ if alignment == both_not_aligned or alignment == tail_aligned:
+ round_up = (region.start % 8)
+ if alignment == both_not_aligned or alignment == head_aligned:
+ round_down = 7 - (region.stop % 8)
+
+ if byte_size <= 1:
+ value_head = IOPortRegionTree.get_first_ioport_byte(
+ region.start, region.stop)
+ if alignment == head_aligned:
+ region.value = value_head
+ else:
+ if alignment == tail_aligned or alignment == both_not_aligned:
+ 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)
+
+ # adjust the region address to make the region aligned
+ if alignment == both_not_aligned or alignment == tail_aligned:
+ region.start -= round_up
+ if alignment == both_not_aligned or alignment == head_aligned:
+ region.stop += round_down
+
+ # the region overlap with the previous region,
+ # so have to modify value and typestr
+ if alignment == tail_aligned or alignment == both_not_aligned:
+ 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()
+ else:
+ region.value = value_head
+
+ # append the region according to the region overlap with the
+ # previous region or not
+ if byte_size <= 1:
+ bitmap_regions.append(region)
+ elif byte_size == 2:
+ if alignment == tail_aligned or alignment == both_not_aligned:
+ stop = region.start + (7 - round_up)
+ value = region.value
+ else:
+ stop = region.start + 7
+ value = 0
+
+ bitmap_regions.append(IOPortRegion(
+ region.start,
+ stop,
+ region.typestr,
+ value))
+ bitmap_regions.append(IOPortRegion(
+ region.stop - (region.stop % 8),
+ region.stop,
+ region.typestr,
+ value_tail))
+ else:
+ if alignment == tail_aligned or alignment == both_not_aligned:
+ stop = region.start + (7 - round_up)
+ value = region.value
+ else:
+ stop = region.stop - (region.stop % 8) - 1
+ value = 0
+
+ bitmap_regions.append(IOPortRegion(
+ region.start,
+ stop,
+ region.typestr,
+ value))
+
+ if alignment == both_not_aligned:
+ bitmap_regions.append(IOPortRegion(
+ region.start + (7 - round_up) + 1,
+ region.stop - (region.stop % 8) - 1,
+ region.typestr,
+ 0))
+
+ if alignment == both_not_aligned or alignment == head_aligned:
+ start = region.stop - (region.stop % 8)
+ value = value_tail
+ else:
+ start = region.start + (7 - round_up) + 1
+ value = 0
+
+ bitmap_regions.append(IOPortRegion(
+ start,
+ region.stop,
+ region.typestr,
+ value))
+
+ # replenishment the region hole
+ 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:
@@ -1458,7 +1613,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')
@@ -1476,7 +1632,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.