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.
