13 Mayıs 2019 Pazartesi 10:40:24 UTC+3 tarihinde [email protected] yazdı:
> Le dimanche 12 mai 2019 09:51:04 UTC+2, Jan Kiszka a écrit :
> > On 10.05.19 15:11, jeanne***.com wrote:
> > > Hello everyone,
> > >
> > > I'm still trying to get my rootCell running. I have for the moment 
> > > connected a serial port in order to have the logs in full (in ssh the 
> > > communication was down before I could have the logs). After solving some 
> > > minor errors (such as Invalid MMIO/RAM read or IO-port) I find myself 
> > > with an error that I can't explain:
> > >
> > >
> > > VT-d fault event reported by IOMMU 1:
> > >   Source Identifier (bus:dev.func): 03:00.0
> > >   Fault Reason: 0x22 Fault Info: 38000000000 Type 0
> > > VT-d fault event reported by IOMMU 1:
> > >   Source Identifier (bus:dev.func): 03:00.0
> > >   Fault Reason: 0x22 Fault Info: 3c000000000 Type 0
> > > VT-d fault event reported by IOMMU 1:
> > >   Source Identifier (bus:dev.func): 03:00.0
> > >   Fault Reason: 0x22 Fault Info: 39000000000 Type 0
> > > VT-d fault event reported by IOMMU 1:
> > >   Source Identifier (bus:dev.func): 03:00.0
> > >   Fault Reason: 0x22 Fault Info: 3b000000000 Type 0
> > >
> > >
> > > Is the new sysfs-parser.py the cause of my trouble or is there anything I 
> > > missed in the configuration ?
> > 
> > Could be. 0x22 means that the device is not present in the interrupt 
> > remapping
> > table of IOMMU that is responsible for that device. Try changing the .iommu
> > number for that device from 0 to 1 or the other way around. Or is there no 
> > entry
> > for 03:00.0 at all?
> > 
> > Jan
> 
> Hello everyone, 
> 
> You can find in attachment my new jailhouse-config-collect. It's actually 
> when y try to enable my root-cell that I have this error so my root-cell is 
> not running and I can't do the "jailhouse cell list". 
> 
> As Jan said I tried to change the .iommu from 1 to 0 for the PCI 03:00.0 but 
> that doesn't change the error ... 
> 
> best regards,

Actually, I done double check for patch. It is parsing everything 
satisfactorily. Also, I parsed DMAR manually. System has two DRHD structure for 
DMAR0 (20:dev.fn subsystems) and DMAR1 (DRHD.flags set INCLUDE_PCI_ALL for the 
others) Thus, 3:0.0 pci device is assigned to DMAR-1 (iommu-1)


I also attached new patched script file for suitable new next branch. I am 
planning to release the patch at new mail and subject (git format-patch).


@Jan 

I have a question about the patch. assign_iommu_info and append_comment_info 
new methods is running for "PCI Express Root Port" or "PCI bridge" primary and 
secondary bus,dev,fn. 

I'm not sure it should work for the primary bus,dev,fn. It doesn't affect the 
result. But I think it shouldn't work. 

Do you have any idea?


Example Device Scope:  (00:1c.7 PCI bridge)

01 0A 00 00 00 00 1C 07 00 00 
01 0A 00 00 00 00 1C 07 00 02 
01 0A 00 00 00 00 1C 07 00 04 

It is running order 

1.) 00:1C.07 
2.) sec-bus:00.00 
3.) 00:1C.07 
4.) sec-bus:00.02 
5.) 00:1C.07 
6.) sec-bus:00.04 

May be it is run for only secondary buses. 

1.) sec-bus:00.00 
2.) sec-bus:00.02 
3.) sec-bus:00.04 





000000h   44 4D 41 52 44 04 00 00   DMARD...    length:00000444
000008h   01 69 48 50 20 20 20 20   .iHP    
000010h   50 72 6F 4C 69 61 6E 74   ProLiant
000018h   01 00 00 00 D2 04 00 00   ....Ò...
000020h   2E 16 00 00 2D 03 00 00   ....-...
000028h   00 00 00 00 00 00 00 00   ........

000030h   00 00 B0 00 00 00 00 00   ..°.....    structType: 0000 (DRHD), 
structLength: 00B0 flags: 00
000038h   00 E0 EF FB 00 00 00 00   .àïû....    base: FBEFE000  (dmar0) 



000040h   02 08 00 00 00 20 00 00   ..... ..    PCI Sub-hierarchy
000048h   02 08 00 00 00 20 01 00   ..... ..    PCI Sub-hierarchy
000050h   02 08 00 00 00 20 01 01   ..... ..    PCI Sub-hierarchy
000058h   02 08 00 00 00 20 02 00   ..... ..    PCI Sub-hierarchy
000060h   02 08 00 00 00 20 02 01   ..... ..    PCI Sub-hierarchy
000068h   02 08 00 00 00 20 02 02   ..... ..    PCI Sub-hierarchy
000070h   02 08 00 00 00 20 02 03   ..... ..    PCI Sub-hierarchy
000078h   02 08 00 00 00 20 03 00   ..... ..    PCI Sub-hierarchy
000080h   02 08 00 00 00 20 03 01   ..... ..    PCI Sub-hierarchy
000088h   02 08 00 00 00 20 03 02   ..... ..    PCI Sub-hierarchy
000090h   02 08 00 00 00 20 03 03   ..... ..    PCI Sub-hierarchy
000098h   03 08 00 00 0A 20 05 04   ..... ..    IOAPIC
0000A0h   01 08 00 00 00 20 04 00   ..... ..    PCI Endpoint Device
0000A8h   01 08 00 00 00 20 04 01   ..... ..    PCI Endpoint Device
0000B0h   01 08 00 00 00 20 04 02   ..... ..    PCI Endpoint Device
0000B8h   01 08 00 00 00 20 04 03   ..... ..    PCI Endpoint Device
0000C0h   01 08 00 00 00 20 04 04   ..... ..    PCI Endpoint Device
0000C8h   01 08 00 00 00 20 04 05   ..... ..    PCI Endpoint Device
0000D0h   01 08 00 00 00 20 04 06   ..... ..    PCI Endpoint Device
0000D8h   01 08 00 00 00 20 04 07   ..... ..    PCI Endpoint Device

===============================================
0000E0h   00 00 28 00 01 00 00 00   ..(.....    structType: 0000 (DRHD), 
structLength: 0028 flags: 01
0000E8h   00 E0 FF F4 00 00 00 00   .àÿô....    base: F4FFE000 (dmar1) 

0000F0h   03 08 00 00 08 00 1E 01   ........    IOAPIC
0000F8h   03 08 00 00 00 00 05 04   ........    IOAPIC
000100h   04 08 00 00 00 00 1F 00   ........    MSI_CAPABLE_HPET



-- 
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].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/8189ed45-40e0-46d7-ae43-8139953068d0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
#
# Jailhouse, a Linux-based partitioning hypervisor
#
# Copyright (c) Siemens AG, 2014-2017
# Copyright (c) Valentine Sinitsyn, 2014-2015
#
# Authors:
#  Henning Schild <[email protected]>
#  Jan Kiszka <[email protected]>
#  Valentine Sinitsyn <[email protected]>
#
# This work is licensed under the terms of the GNU GPL, version 2.  See
# the COPYING file in the top-level directory.
#
# This script should help to create a basic jailhouse configuration file.
# It needs to be executed on the target machine, where it will gather
# information about the system. For more advanced scenarios you will have
# to change the generated C-code.


import struct
import os
import fnmatch

from .pci_defs import PCI_CAP_ID, PCI_EXT_CAP_ID

root_dir = "/"


def set_root_dir(dir):
    global root_dir
    root_dir = dir

inputs = {
    'files': set(),
    'files_opt': set(),
    'files_intel': set(),
    'files_amd': set()
}

# required files
inputs['files'].add('/proc/iomem')
inputs['files'].add('/proc/cpuinfo')
inputs['files'].add('/proc/cmdline')
inputs['files'].add('/proc/ioports')
inputs['files'].add('/sys/bus/pci/devices/*/config')
inputs['files'].add('/sys/bus/pci/devices/*/resource')
inputs['files'].add('/sys/devices/system/cpu/cpu*/uevent')
inputs['files'].add('/sys/firmware/acpi/tables/APIC')
inputs['files'].add('/sys/firmware/acpi/tables/MCFG')
# optional files
inputs['files_opt'].add('/sys/class/dmi/id/product_name')
inputs['files_opt'].add('/sys/class/dmi/id/sys_vendor')
inputs['files_opt'].add('/sys/class/tty/*/iomem_base')
inputs['files_opt'].add('/sys/class/tty/*/iomem_reg_shift')
inputs['files_opt'].add('/sys/class/tty/*/io_type')
inputs['files_opt'].add('/sys/class/tty/*/port')
inputs['files_opt'].add('/sys/devices/jailhouse/enabled')
# platform specific files
inputs['files_intel'].add('/sys/firmware/acpi/tables/DMAR')
inputs['files_amd'].add('/sys/firmware/acpi/tables/IVRS')


def check_input_listed(name, optional=False):
    set = inputs['files_opt']
    if optional is False:
        set = inputs['files']
        cpuvendor = get_cpu_vendor()
        if cpuvendor == 'GenuineIntel':
            set = set.union(inputs['files_intel'])
        elif cpuvendor == 'AuthenticAMD':
            set = set.union(inputs['files_amd'])

    for file in set:
        if fnmatch.fnmatch(name, file):
            return True
    raise RuntimeError('"' + name + '" is not a listed input file')


def input_open(name, mode='r', optional=False):
    check_input_listed(name, optional)
    try:
        f = open(root_dir + name, mode)
    except Exception as e:
        if optional:
            return open("/dev/null", mode)
        raise e
    return f


def input_listdir(dir, wildcards):
    for w in wildcards:
        check_input_listed(os.path.join(dir, w))
    dirs = os.listdir(root_dir + dir)
    dirs.sort()
    return dirs


def parse_iomem(pcidevices):
    (regions, dmar_regions) = IOMemRegionTree.parse_iomem_tree(
        IOMemRegionTree.parse_iomem_file())

    rom_region = MemRegion(0xc0000, 0xdffff, 'ROMs')
    add_rom_region = False

    ret = []
    for r in regions:
        append_r = True
        # filter the list for MSI-X pages
        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)
                    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)
                    ret.append(tail_r)
                append_r = False
                break
        # filter out the ROMs
        if (r.start >= rom_region.start and r.stop <= rom_region.stop):
            add_rom_region = True
            append_r = False
        # filter out and save DMAR regions
        if r.typestr.find('dmar') >= 0:
            dmar_regions.append(r)
            append_r = False
        if append_r:
            ret.append(r)

    # add a region that covers all potential ROMs
    if add_rom_region:
        ret.append(rom_region)

    # newer Linux kernels will report the first page as reserved
    # it is needed for CPU init so include it anyways
    if (ret[0].typestr == 'System RAM' and ret[0].start == 0x1000):
        ret[0].start = 0

    return ret, dmar_regions


def parse_pcidevices():
    int_src_cnt = 0
    devices = []
    caps = []
    basedir = '/sys/bus/pci/devices'
    list = input_listdir(basedir, ['*/config'])
    for dir in list:
        d = PCIDevice.parse_pcidevice_sysfsdir(basedir, dir)
        if d is not None:
            if len(d.caps) > 0:
                duplicate = False
                # look for duplicate capability patterns
                for d2 in devices:
                    if d2.caps == d.caps:
                        # reused existing capability list, but record all users
                        d2.caps[0].comments.append(str(d))
                        d.caps_start = d2.caps_start
                        duplicate = True
                        break
                if not duplicate:
                    d.caps[0].comments.append(str(d))
                    d.caps_start = len(caps)
                    caps.extend(d.caps)
            int_src_cnt += max(d.num_msi_vectors, d.num_msix_vectors)
            devices.append(d)
    return (devices, caps, int_src_cnt)


def parse_madt():
    f = input_open('/sys/firmware/acpi/tables/APIC', 'rb')
    signature = f.read(4)
    if signature != b'APIC':
        raise RuntimeError('MADT: incorrect input file format %s' % signature)
    (length,) = struct.unpack('<I', f.read(4))
    f.seek(44)
    length -= 44
    ioapics = []

    while length > 0:
        offset = 0
        (struct_type, struct_len) = struct.unpack('<BB', f.read(2))
        offset += 2
        length -= struct_len

        if struct_type == 1:
            (id, address, gsi_base) = struct.unpack('<BxII', f.read(10))
            offset += 10
            ioapics.append(IOAPIC(id, address, gsi_base))

        f.seek(struct_len - offset, os.SEEK_CUR)

    f.close()
    return ioapics


def assign_iommu_info(flags, pcidevices, units, ioapics, scope_type, id, bus, dev, fn):
    # PCI Endpoint Device
    if scope_type == 1:
        assert not (flags & 1)
        for d in pcidevices:
            if d.bus == bus and d.dev == dev and d.fn == fn:
                d.iommu = len(units) - 1
                break
    # PCI Sub-hierarchy
    elif scope_type == 2:
        assert not (flags & 1)
        for d in pcidevices:
            if d.bus == bus and d.dev == dev and d.fn == fn:
                (secondbus, subordinate) = \
                    PCIPCIBridge.get_2nd_busses(d)
                for d2 in pcidevices:
                    if (
                        d2.bus >= secondbus and
                        d2.bus <= subordinate
                    ):
                        d2.iommu = len(units) - 1
                break
    # IOAPIC
    elif scope_type == 3:
        ioapic = next(chip for chip in ioapics if chip.id == id)
        bdf = (bus << 8) | (dev << 3) | fn
        for chip in ioapics:
            if chip.bdf == bdf:
                raise RuntimeError('IOAPICs with identical BDF')
        ioapic.bdf = bdf
        ioapic.iommu = len(units) - 1


def append_comment_info(comments, scope_type, bus, dev, fn):
    if scope_type == 1:
        comments.append('PCI device: %02x:%02x.%x' %
                        (bus, dev, fn))
    else:
        comments.append('DMAR parser could not decode device path')


# parsing of DMAR ACPI Table
# see Intel VT-d Spec chapter 8
def parse_dmar(pcidevices, ioapics, dmar_regions):
    f = input_open('/sys/firmware/acpi/tables/DMAR', 'rb')
    signature = f.read(4)
    if signature != b'DMAR':
        raise RuntimeError('DMAR: incorrect input file format %s' % signature)
    (length,) = struct.unpack('<I', f.read(4))
    f.seek(48)
    length -= 48
    units = []
    regions = []

    while length > 0:
        offset = 0
        (struct_type, struct_len) = struct.unpack('<HH', f.read(4))
        offset += 4
        length -= struct_len

        # DMA Remapping Hardware Unit Definition
        if struct_type == 0:
            (flags, segment, base) = struct.unpack('<BxHQ', f.read(12))
            if segment != 0:
                raise RuntimeError('We do not support multiple PCI segments')
            if len(units) >= 8:
                raise RuntimeError('Too many DMAR units. '
                                   'Raise JAILHOUSE_MAX_IOMMU_UNITS.')
            size = 0
            for r in dmar_regions:
                if base == r.start:
                    size = r.size()
            if size == 0:
                raise RuntimeError('DMAR region size cannot be identified.\n'
                                   'Target Linux must run with Intel IOMMU '
                                   'enabled.')
            if size > 0x3000:
                raise RuntimeError('Unexpectedly large DMAR region.')
            units.append(IOMMUConfig({
                'base_addr': base,
                'mmio_size': size
            }))
            if flags & 1:
                for d in pcidevices:
                    if d.iommu is None:
                        d.iommu = len(units) - 1
            offset += 16 - offset
            while offset < struct_len:
                (scope_type, scope_len) = struct.unpack('<BB', f.read(2))

                N = (int)((scope_len - 6) / 2) - 1

                (id, starting_bus, starting_dev, starting_fn) = struct.unpack(
                                                        '<xxBBBB', f.read(6))

                assign_iommu_info(flags, pcidevices, units, ioapics, \
                    scope_type, id, starting_bus, starting_dev, starting_fn)

                while N != 0:
                    N -= 1
                    (secondary_dev, secondary_fn) = \
                                    struct.unpack('<BB', f.read(2))
                    for d in pcidevices:
                        if d.bus == starting_bus and d.dev == starting_dev \
                                                 and d.fn == starting_fn:
                            (secondbus, subordinate) = \
                                PCIPCIBridge.get_2nd_busses(d)
                            break
                    assign_iommu_info(flags, pcidevices, units, ioapics, \
                        scope_type, id, secondbus, secondary_dev, \
                        secondary_fn)
                offset += scope_len

        # Reserved Memory Region Reporting Structure
        if struct_type == 1:
            f.seek(8 - offset, os.SEEK_CUR)
            offset += 8 - offset
            (base, limit) = struct.unpack('<QQ', f.read(16))
            offset += 16

            comments = []
            while offset < struct_len:
                (scope_type, scope_len) = struct.unpack('<BB', f.read(2))

                N = (int)((scope_len - 6) / 2) - 1

                (id, starting_bus, starting_dev, starting_fn) = struct.unpack(
                                                    '<xxBBBB', f.read(6))

                append_comment_info(comments, scope_type, starting_bus, \
                                                starting_dev, starting_fn)

                while N != 0:
                    N -= 1
                    (secondary_dev, secondary_fn) = struct.unpack(
                                                    '<BB', f.read(2))
                    for d in pcidevices:
                        if d.bus == starting_bus and d.dev == starting_dev \
                                                 and d.fn == starting_fn:
                            (secondbus, subordinate) = \
                                    PCIPCIBridge.get_2nd_busses(d)
                            break

                    append_comment_info(comments, scope_type, secondbus, \
                                                secondary_dev, secondary_fn)
                offset += scope_len

            reg = MemRegion(base, limit, 'ACPI DMAR RMRR', comments)
            regions.append(reg)

        f.seek(struct_len - offset, os.SEEK_CUR)

    f.close()

    for d in pcidevices:
        if d.iommu is None:
            raise RuntimeError(
                'PCI device %02x:%02x.%x outside the scope of an '
                'IOMMU' % (d.bus, d.dev, d.fn))

    return units, regions


def parse_ivrs(pcidevices, ioapics):
    def format_bdf(bdf):
        bus, dev, fun = (bdf >> 8) & 0xff, (bdf >> 3) & 0x1f, bdf & 0x7
        return '%02x:%02x.%x' % (bus, dev, fun)

    f = input_open('/sys/firmware/acpi/tables/IVRS', 'rb')
    signature = f.read(4)
    if signature != b'IVRS':
        raise RuntimeError('IVRS: incorrect input file format %s' % signature)

    (length, revision) = struct.unpack('<IB', f.read(5))
    if revision > 2:
        raise RuntimeError('IVRS: unsupported Revision %02x' % revision)

    f.seek(48, os.SEEK_SET)
    length -= 48

    units = []
    regions = []
    # BDF of devices that are permitted outside IOMMU: root complex
    iommu_skiplist = set([0x0])
    ivhd_blocks = 0
    while length > 0:
        (block_type, block_length) = struct.unpack('<BxH', f.read(4))
        if block_type in [0x10, 0x11]:
            ivhd_blocks += 1
            if ivhd_blocks > 1:
                raise RuntimeError('Jailhouse doesn\'t support more than one '
                                   'AMD IOMMU per PCI function.')
            # IVHD block
            ivhd_fields = struct.unpack('<HHQHxxL', f.read(20))
            (iommu_bdf, base_cap_ofs,
             base_addr, pci_seg, iommu_feat) = ivhd_fields

            length -= block_length
            block_length -= 24

            if pci_seg != 0:
                raise RuntimeError('We do not support multiple PCI segments')

            if len(units) > 8:
                raise RuntimeError('Too many IOMMU units. '
                                   'Raise JAILHOUSE_MAX_IOMMU_UNITS.')

            msi_cap_ofs = None

            for i, d in enumerate(pcidevices):
                if d.bdf() == iommu_bdf:
                    # Extract MSI capability offset
                    for c in d.caps:
                        if c.id == PCI_CAP_ID.MSI:
                            msi_cap_ofs = c.start
                    # We must not map IOMMU to the cells
                    del pcidevices[i]

            if msi_cap_ofs is None:
                raise RuntimeError('AMD IOMMU lacks MSI support, and '
                                   'Jailhouse doesn\'t support MSI-X yet.')

            if (iommu_feat & (0xF << 13)) and (iommu_feat & (0x3F << 17)):
                # Performance Counters are supported, allocate 512K
                mmio_size = 524288
            else:
                # Allocate 16K
                mmio_size = 16384

            units.append(IOMMUConfig({
                'base_addr': base_addr,
                'mmio_size': mmio_size,
                'amd_bdf': iommu_bdf,
                'amd_base_cap': base_cap_ofs,
                'amd_msi_cap': msi_cap_ofs,
                # IVHD block type 0x11 has exact EFR copy but type 0x10 may
                # overwrite what hardware reports. Set reserved bit 0 in that
                # case to indicate that the value is in use.
                'amd_features': (iommu_feat | 0x1) if block_type == 0x10 else 0
            }))

            bdf_start_range = None
            while block_length > 0:
                (entry_type, device_id) = struct.unpack('<BHx', f.read(4))
                block_length -= 4

                if entry_type == 0x01:
                    # All
                    for d in pcidevices:
                        d.iommu = len(units) - 1
                elif entry_type == 0x02:
                    # Select
                    for d in pcidevices:
                        if d.bdf() == device_id:
                            d.iommu = len(units) - 1
                elif entry_type == 0x03:
                    # Start of range
                    bdf_start_range = device_id
                elif entry_type == 0x04:
                    # End of range
                    if bdf_start_range is None:
                        continue
                    for d in pcidevices:
                        if d.bdf() >= bdf_start_range and d.bdf() <= device_id:
                            d.iommu = len(units) - 1
                    bdf_start_range = None
                elif entry_type == 0x42:
                    # Alias select
                    (device_id_b,) = struct.unpack('<xHx', f.read(4))
                    block_length -= 4
                    for d in pcidevices:
                        if d.bdf() == device_id_b:
                            d.iommu = len(units) - 1
                elif entry_type == 0x43:
                    # Alias start of range
                    (device_id_b,) = struct.unpack('<xHx', f.read(4))
                    block_length -= 4
                    bdf_start_range = device_id_b
                elif entry_type == 0x48:
                    # Special device
                    (handle, device_id_b, variety) = struct.unpack(
                        '<BHB', f.read(4))
                    block_length -= 4
                    if variety == 0x01:  # IOAPIC
                        for chip in ioapics:
                            if chip.id == handle:
                                chip.bdf = device_id_b
                                chip.iommu = len(units) - 1
                else:
                    # Reserved or ignored entries
                    if entry_type >= 0x40:
                        f.seek(4, os.SEEK_CUR)
                        block_length -= 4

        elif type in [0x20, 0x21, 0x22]:
            # IVMD block
            ivmd_fields = struct.unpack('<BBHHHxxxxxxxxQQ', f.read(32))
            (block_type, block_flags, block_length,
             device_id, aux_data, mem_addr, mem_len) = ivmd_fields
            length -= block_length

            if int(block_flags):
                bdf_str = format_bdf(device_id)
                print(
                    'WARNING: Jailhouse doesn\'t support configurable '
                    '(eg. read-only) device memory. Device %s may not '
                    'work properly, especially in non-root cell.' % bdf_str)

            if block_type == 0x20:
                # All devices
                comment = None
            elif block_type == 0x21:
                # Selected device
                comment = 'PCI Device: %s' % format_bdf(device_id)
            elif block_type == 0x22:
                # Device range
                comment = 'PCI Device: %s - %s' % (
                    format_bdf(device_id), format_bdf(aux_data))

            if comment:
                print('WARNING: Jailhouse doesn\'t support per-device memory '
                      '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))
        elif type == 0x40:
            raise RuntimeError(
                'You board uses IVRS Rev. 2 feature Jailhouse doesn\'t '
                'support yet. Please report this to '
                '[email protected].')
        else:
            print(
                'WARNING: Skipping unknown IVRS '
                'block type 0x%02x' % block_type)

        for d in pcidevices:
            if d.bdf() not in iommu_skiplist and d.iommu is None:
                raise RuntimeError(
                    'PCI device %02x:%02x.%x outside the scope of an '
                    'IOMMU' % (d.bus, d.dev, d.fn))

        f.close()
        return units, regions


def get_cpu_vendor():
    with open(root_dir + '/proc/cpuinfo') as f:
        for line in f:
            if not line.strip():
                continue
            key, value = line.split(':')
            if key.strip() == 'vendor_id':
                return value.strip()


class PCIBARs:
    IORESOURCE_IO = 0x00000100
    IORESOURCE_MEM = 0x00000200
    IORESOURCE_MEM_64 = 0x00100000

    def __init__(self, dir):
        self.mask = []
        f = input_open(os.path.join(dir, 'resource'), 'r')
        n = 0
        while (n < 6):
            (start, end, flags) = f.readline().split()
            n += 1
            flags = int(flags, 16)
            if flags & PCIBARs.IORESOURCE_IO:
                mask = ~(int(end, 16) - int(start, 16))
            elif flags & PCIBARs.IORESOURCE_MEM:
                if flags & PCIBARs.IORESOURCE_MEM_64:
                    mask = int(end, 16) - int(start, 16)
                    (start, end, flags) = f.readline().split()
                    mask |= (int(end, 16) - int(start, 16)) << 32
                    mask = ~(mask)
                    self.mask.append(mask & 0xffffffff)
                    mask >>= 32
                    n += 1
                else:
                    mask = ~(int(end, 16) - int(start, 16))
            else:
                mask = 0
            self.mask.append(mask & 0xffffffff)
        f.close()


class PCICapability:
    def __init__(self, id, extended, start, len, flags, content, msix_address):
        self.id = id
        self.extended = extended
        self.start = start
        self.len = len
        self.flags = flags
        self.content = content
        self.msix_address = msix_address
        self.comments = []

    def __eq__(self, other):
        return self.id == other.id and self.start == other.start and \
            self.len == other.len and self.flags == other.flags

    def gen_id_str(self):
        return str(self.id) + \
            (' | JAILHOUSE_PCI_EXT_CAP' if self.extended else '')

    RD = '0'
    RW = 'JAILHOUSE_PCICAPS_WRITE'

    JAILHOUSE_PCI_EXT_CAP = 0x8000

    @staticmethod
    def parse_pcicaps(dir):
        caps = []
        has_extended_caps = False
        f = input_open(os.path.join(dir, 'config'), 'rb')
        f.seek(0x06)
        (status,) = struct.unpack('<H', f.read(2))
        # capability list supported?
        if (status & (1 << 4)) == 0:
            f.close()
            return caps
        # walk capability list
        f.seek(0x34)
        (next,) = struct.unpack('B', f.read(1))
        while next != 0:
            cap = next
            msix_address = 0
            f.seek(cap)
            (id, next) = struct.unpack('<BB', f.read(2))
            id = PCI_CAP_ID(id)
            if id == PCI_CAP_ID.PM:
                # this cap can be handed out completely
                len = 8
                flags = PCICapability.RW
            elif id == PCI_CAP_ID.MSI:
                # access will be moderated by hypervisor
                len = 10
                (msgctl,) = struct.unpack('<H', f.read(2))
                if (msgctl & (1 << 7)) != 0:  # 64-bit support
                    len += 4
                if (msgctl & (1 << 8)) != 0:  # per-vector masking support
                    len += 10
                flags = PCICapability.RW
            elif id == PCI_CAP_ID.EXP:
                len = 20
                (cap_reg,) = struct.unpack('<H', f.read(2))
                if (cap_reg & 0xf) >= 2:  # v2 capability
                    len = 60
                # access side effects still need to be analyzed
                flags = PCICapability.RD
                has_extended_caps = True
            elif id == PCI_CAP_ID.MSIX:
                # access will be moderated by hypervisor
                len = 12
                (table,) = struct.unpack('<xxI', f.read(6))
                f.seek(0x10 + (table & 7) * 4)
                (bar,) = struct.unpack('<I', f.read(4))
                if (bar & 0x3) != 0:
                    raise RuntimeError('Invalid MSI-X BAR found')
                if (bar & 0x4) != 0:
                    bar |= struct.unpack('<I', f.read(4))[0] << 32
                msix_address = \
                    (bar & 0xfffffffffffffff0) + (table & 0xfffffff8)
                flags = PCICapability.RW
            else:
                # unknown/unhandled cap, mark its existence
                len = 2
                flags = PCICapability.RD
            f.seek(cap + 2)
            content = f.read(len - 2)
            caps.append(PCICapability(id, False, cap, len, flags, content,
                                      msix_address))

        if has_extended_caps:
            # walk extended capability list
            next = 0x100
            while next != 0:
                cap = next
                f.seek(cap)
                (id, version_next) = struct.unpack('<HH', f.read(4))
                if id == 0xffff:
                    break
                elif (id & PCICapability.JAILHOUSE_PCI_EXT_CAP) != 0:
                    print('WARNING: Ignoring unsupported PCI Express '
                          'Extended Capability ID %x' % id)
                    continue

                id = PCI_EXT_CAP_ID(id)
                next = version_next >> 4
                if id == PCI_EXT_CAP_ID.SRIOV:
                    len = 64
                    # access side effects still need to be analyzed
                    flags = PCICapability.RD
                else:
                    # unknown/unhandled cap, mark its existence
                    len = 4
                    flags = PCICapability.RD
                f.seek(cap + 4)
                content = f.read(len - 4)
                caps.append(PCICapability(id, True, cap, len, flags, content,
                                          0))

        f.close()
        return caps


class PCIDevice:
    def __init__(self, type, domain, bus, dev, fn, bars, caps, path):
        self.type = type
        self.iommu = None
        self.domain = domain
        self.bus = bus
        self.dev = dev
        self.fn = fn
        self.bars = bars
        self.caps = caps
        self.path = path
        self.caps_start = 0
        self.num_caps = len(caps)
        self.num_msi_vectors = 0
        self.msi_64bits = 0
        self.num_msix_vectors = 0
        self.msix_region_size = 0
        self.msix_address = 0
        for c in caps:
            if c.id in (PCI_CAP_ID.MSI, PCI_CAP_ID.MSIX):
                msg_ctrl = struct.unpack('<H', c.content[:2])[0]
                if c.id == PCI_CAP_ID.MSI:
                    self.num_msi_vectors = 1 << ((msg_ctrl >> 1) & 0x7)
                    self.msi_64bits = (msg_ctrl >> 7) & 1
                else:  # MSI-X
                    if c.msix_address != 0:
                        vectors = (msg_ctrl & 0x7ff) + 1
                        self.num_msix_vectors = vectors
                        self.msix_region_size = (vectors * 16 + 0xfff) & 0xf000
                        self.msix_address = c.msix_address
                    else:
                        print('WARNING: Ignoring invalid MSI-X configuration'
                              ' of device %02x:%02x.%x' % (bus, dev, fn))

    def __str__(self):
        return 'PCIDevice: %02x:%02x.%x' % (self.bus, self.dev, self.fn)

    def bdf(self):
        return self.bus << 8 | self.dev << 3 | self.fn

    @staticmethod
    def parse_pcidevice_sysfsdir(basedir, dir):
        dpath = os.path.join(basedir, dir)
        f = input_open(os.path.join(dpath, 'config'), 'rb')
        (vendor_device,) = struct.unpack('<I', f.read(4))
        if vendor_device == 0xffffffff:
            print('WARNING: Ignoring apparently disabled PCI device %s' % dir)
            return None
        f.seek(0x0A)
        (classcode,) = struct.unpack('<H', f.read(2))
        f.close()
        if classcode == 0x0604:
            type = 'JAILHOUSE_PCI_TYPE_BRIDGE'
        else:
            type = 'JAILHOUSE_PCI_TYPE_DEVICE'
        a = dir.split(':')
        domain = int(a[0], 16)
        bus = int(a[1], 16)
        df = a[2].split('.')
        bars = PCIBARs(dpath)
        caps = PCICapability.parse_pcicaps(dpath)
        return PCIDevice(type, domain, bus, int(df[0], 16), int(df[1], 16),
                         bars, caps, dpath)


class PCIPCIBridge(PCIDevice):
    @staticmethod
    def get_2nd_busses(dev):
        assert dev.type == 'JAILHOUSE_PCI_TYPE_BRIDGE'
        f = input_open(os.path.join(dev.path, 'config'), 'rb')
        f.seek(0x19)
        (secondbus, subordinate) = struct.unpack('<BB', f.read(2))
        f.close()
        return (secondbus, subordinate)


class MemRegion:
    def __init__(self, start, stop, typestr, comments=None):
        self.start = start
        self.stop = stop
        self.typestr = typestr
        self.comments = comments or []

    def __str__(self):
        return 'MemRegion: %08x-%08x : %s' % \
            (self.start, self.stop, self.typestr)

    def size(self):
        # round up to full PAGE_SIZE
        return int((self.stop - self.start + 0xfff) / 0x1000) * 0x1000

    def flagstr(self, p=''):
        if (
            self.typestr == 'System RAM' or
            self.typestr == 'Kernel' or
            self.typestr == 'RAM buffer' or
            self.typestr == 'ACPI DMAR RMRR' or
            self.typestr == 'ACPI IVRS'
        ):
            s = 'JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |\n'
            s += p + '\t\tJAILHOUSE_MEM_EXECUTE | JAILHOUSE_MEM_DMA'
            return s
        return 'JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE'


class IOAPIC:
    def __init__(self, id, address, gsi_base, iommu=0, bdf=0):
        self.id = id
        self.address = address
        self.gsi_base = gsi_base
        self.iommu = iommu
        self.bdf = bdf

    def __str__(self):
        return 'IOAPIC %d, GSI base %d' % (self.id, self.gsi_base)

    def irqchip_id(self):
        # encode the IOMMU number into the irqchip ID
        return (self.iommu << 16) | self.bdf


class IOMemRegionTree:
    def __init__(self, region, level):
        self.region = region
        self.level = level
        self.parent = None
        self.children = []

    def __str__(self):
        s = ''
        if (self.region):
            s = (' ' * (self.level - 1)) + str(self.region)
            if self.parent and self.parent.region:
                s += ' --> ' + self.parent.region.typestr
            s += '\n'
        for c in self.children:
            s += str(c)
        return s

    def regions_split_by_kernel(self):
        kernel = [x for x in self.children if
                  x.region.typestr.startswith('Kernel ')]

        if (len(kernel) == 0):
            return [self.region]

        r = self.region
        s = r.typestr

        kernel_start = kernel[0].region.start
        kernel_stop = kernel[len(kernel) - 1].region.stop

        # align this for 16M, but only if we have enough space
        kernel_stop = (kernel_stop & ~0xFFFFFF) + 0xFFFFFF
        if (kernel_stop > r.stop):
            kernel_stop = r.stop

        before_kernel = None
        after_kernel = None

        # before Kernel if any
        if (r.start < kernel_start):
            before_kernel = MemRegion(r.start, kernel_start - 1, s)

        kernel_region = MemRegion(kernel_start, kernel_stop, "Kernel")

        # after Kernel if any
        if (r.stop > kernel_stop):
            after_kernel = MemRegion(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)
            t = IOMemRegionTree(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

    # find specific regions in tree
    @staticmethod
    def find_regions_by_name(tree, name):
        regions = []

        for tree in tree.children:
            r = tree.region
            s = r.typestr

            if (s.find(name) >= 0):
                regions.append(r)

            # if the tree continues recurse further down ...
            if (len(tree.children) > 0):
                regions.extend(
                    IOMemRegionTree.find_regions_by_name(tree, name))

        return regions

    # recurse down the tree
    @staticmethod
    def parse_iomem_tree(tree):
        regions = []
        dmar_regions = []

        for tree in tree.children:
            r = tree.region
            s = r.typestr

            # System RAM on the first level will be added completely,
            # if they don't contain the kernel itself, if they do,
            # we split them
            if (tree.level == 1 and s == 'System RAM'):
                regions.extend(tree.regions_split_by_kernel())
                continue

            # blacklisted on all levels
            if (
                (s.find('PCI MMCONFIG') >= 0) or
                (s.find('APIC') >= 0)  # covers both APIC and IOAPIC
            ):
                continue

            # generally blacklisted, with a few exceptions
            if (s.lower() == 'reserved'):
                regions.extend(
                    IOMemRegionTree.find_regions_by_name(tree, 'HPET'))
                dmar_regions.extend(
                    IOMemRegionTree.find_regions_by_name(tree, 'dmar'))
                continue

            # if the tree continues recurse further down ...
            if (len(tree.children) > 0):
                (temp_regions, temp_dmar_regions) = \
                    IOMemRegionTree.parse_iomem_tree(tree)
                regions.extend(temp_regions)
                dmar_regions.extend(temp_dmar_regions)
                continue

            # add all remaining leaves
            regions.append(r)

        return regions, dmar_regions


class IOMMUConfig:
    def __init__(self, props):
        self.base_addr = props['base_addr']
        self.mmio_size = props['mmio_size']
        if 'amd_bdf' in props:
            self.amd_bdf = props['amd_bdf']
            self.amd_base_cap = props['amd_base_cap']
            self.amd_msi_cap = props['amd_msi_cap']
            self.amd_features = props['amd_features']

    @property
    def is_amd_iommu(self):
        return hasattr(self, 'amd_bdf')
fbefe000-fbefefff : dmar0
f4ffe000-f4ffefff : dmar1


(DRHD).flags

Bit 0: INCLUDE_PCI_ALL
• If Clear, this remapping hardware unit has under its scope only
devices in the specified Segment that are explicitly identified through
the ‘Device Scope’ field.


• If Set, this remapping hardware unit has under its scope all PCI
compatible devices in the specified Segment, except devices reported
under the scope of other remapping hardware units for the same
Segment. 

If a DRHD structure with INCLUDE_PCI_ALL flag Set is
reported for a Segment, it must be enumerated by BIOS after all
other DRHD structures for the same Segment 1 . 

A DRHD structure with
INCLUDE_PCI_ALL flag Set may use the ‘Device Scope’ field to
enumerate I/OxAPIC and HPET devices under its scope.


=================================================================================================================================================


000000h   44 4D 41 52 44 04 00 00   DMARD...    length:00000444
000008h   01 69 48 50 20 20 20 20   .iHP    
000010h   50 72 6F 4C 69 61 6E 74   ProLiant
000018h   01 00 00 00 D2 04 00 00   ....Ò...
000020h   2E 16 00 00 2D 03 00 00   ....-...
000028h   00 00 00 00 00 00 00 00   ........

000030h   00 00 B0 00 00 00 00 00   ..°.....    structType: 0000 (DRHD), 
structLength: 00B0 flags: 00
000038h   00 E0 EF FB 00 00 00 00   .àïû....    base: FBEFE000  (dmar0)

000040h   02 08 00 00 00 20 00 00   ..... ..    PCI Sub-hierarchy
000048h   02 08 00 00 00 20 01 00   ..... ..    PCI Sub-hierarchy
000050h   02 08 00 00 00 20 01 01   ..... ..    PCI Sub-hierarchy
000058h   02 08 00 00 00 20 02 00   ..... ..    PCI Sub-hierarchy
000060h   02 08 00 00 00 20 02 01   ..... ..    PCI Sub-hierarchy
000068h   02 08 00 00 00 20 02 02   ..... ..    PCI Sub-hierarchy
000070h   02 08 00 00 00 20 02 03   ..... ..    PCI Sub-hierarchy
000078h   02 08 00 00 00 20 03 00   ..... ..    PCI Sub-hierarchy
000080h   02 08 00 00 00 20 03 01   ..... ..    PCI Sub-hierarchy
000088h   02 08 00 00 00 20 03 02   ..... ..    PCI Sub-hierarchy
000090h   02 08 00 00 00 20 03 03   ..... ..    PCI Sub-hierarchy
000098h   03 08 00 00 0A 20 05 04   ..... ..    IOAPIC
0000A0h   01 08 00 00 00 20 04 00   ..... ..    PCI Endpoint Device
0000A8h   01 08 00 00 00 20 04 01   ..... ..    PCI Endpoint Device
0000B0h   01 08 00 00 00 20 04 02   ..... ..    PCI Endpoint Device
0000B8h   01 08 00 00 00 20 04 03   ..... ..    PCI Endpoint Device
0000C0h   01 08 00 00 00 20 04 04   ..... ..    PCI Endpoint Device
0000C8h   01 08 00 00 00 20 04 05   ..... ..    PCI Endpoint Device
0000D0h   01 08 00 00 00 20 04 06   ..... ..    PCI Endpoint Device
0000D8h   01 08 00 00 00 20 04 07   ..... ..    PCI Endpoint Device

===============================================
0000E0h   00 00 28 00 01 00 00 00   ..(.....    structType: 0000 (DRHD), 
structLength: 0028 flags: 01
0000E8h   00 E0 FF F4 00 00 00 00   .àÿô....    base: F4FFE000 (dmar1) 

0000F0h   03 08 00 00 08 00 1E 01   ........    IOAPIC
0000F8h   03 08 00 00 00 00 05 04   ........    IOAPIC
000100h   04 08 00 00 00 00 1F 00   ........    MSI_CAPABLE_HPET

===============================================
000108h   01 00 28 00 00 00 00 00   ..(.....    structType: 0001, structLength: 
0028
000110h   00 D0 FF BD 00 00 00 00   .Ðÿ½....
000118h   FF FF FF BD 00 00 00 00   ÿÿÿ½....

000120h   01 08 00 00 00 00 1D 00   ........    PCI Endpoint Device
000128h   01 08 00 00 00 00 1A 00   ........    PCI Endpoint Device

===============================================
000130h   01 00 36 00 00 00 00 00   ..6.....    structType: 0001, structLength: 
0036
000138h   00 60 FF BD 00 00 00 00   .`ÿ½....
000140h   FF CF FF BD 00 00 00 00   ÿÏÿ½....

        01 0A 00 00 00 00 1C 07 00 00   ........        PCI Endpoint Device 
(size A)
        01 0A 00 00 00 00 1C 07 00 02   ........        PCI Endpoint Device 
(size A)
        01 0A 00 00 00 00 1C 07 00 04   ........        PCI Endpoint Device 
(size A)
 

===============================================
                            01 00   ........    structType: 0001, structLength: 
006E                            
000168h   6E 00 00 00 00 00 00 30   n......0
000170h   F8 BD 00 00 00 00 FF 4F   ø½....ÿO
000178h   F8 BD 00 00 00 00 

        01 0A 00 00 00 00 02 02 00 00           00:02.02 and [02]----00.0  
Hewlett-Packard Company Smart Array Gen8 Controllers
        01 0A 00 00 00 00 1C 07 00 00           00:1C.07 and [01]--+-00.0
        01 0A 00 00 00 00 1C 07 00 02           00:1C.07 and [01]--+-00.2
        01 08 00 00 00 00 1F 02                 00:1F.02
        01 08 00 00 00 00 1F 05                 00:1F.05
        01 0A 00 00 00 00 02 00 00 00           00:02.00 and [03]--+-00.0  
Broadcom Corporation NetXtreme BCM5719 Gigabit Ethernet PCIe
        01 0A 00 00 00 00 02 00 00 01           00:02.00 and [03]--+-00.1  
Broadcom Corporation NetXtreme BCM5719 Gigabit Ethernet PCIe   
        01 0A 00 00 00 00 02 00 00 02           00:02.00 and [03]--+-00.2  
Broadcom Corporation NetXtreme BCM5719 Gigabit Ethernet PCIe
        01 0A 00 00 00 00 02 00 00 03           00:02.00 and [03]--+-00.3  
Broadcom Corporation NetXtreme BCM5719 Gigabit Ethernet PCIe
===============================================
                      01 00 6E 00   ......n.    structType: 0001, structLength: 
006E
0001D8h   00 00 00 00 00 F0 F7 BD   .....ð÷½
0001E0h   00 00 00 00 FF 2F F8 BD   ....ÿ/ø½
0001E8h   00 00 00 00 

        01 0A 00 00 00 00 02 02 00 00           00:02.02 and [02]----00.0   
        01 0A 00 00 00 00 1C 07 00 00           00:1C.07 and [01]--+-00.0  
        01 0A 00 00 00 00 1C 07 00 02           00:1C.07 and [01]--+-00.2 
        01 08 00 00 00 00 1F 02                 00:1F.02
        01 08 00 00 00 00 1F 05                 00:1F.05
        01 0A 00 00 00 00 02 00 00 00 
        01 0A 00 00 00 00 02 00 00 01 
        01 0A 00 00 00 00 02 00 00 02   
        01 0A 00 00 00 00 02 00 00 03
 
===============================================
                01 00 6E 00 00 00   ....n...    structType: 0001, structLength: 
006E
000248h   00 00 00 F0 F6 BD 00 00   ...ðö½..
000250h   00 00 FF EF F7 BD 00 00   ..ÿï÷½..
000258h   00 00 

        01 0A 00 00 00 00 02 02 00 00 
        01 0A 00 00 00 00 1C 07 00 00 
        01 0A 00 00 00 00 1C 07 00 02   
        01 08 00 00 00 00 1F 02   
        01 08 0 00 00 00 1F 05   
        01 0A 00 00 00 00 02 00 00 00 
        01 0A 00 00 00 00 02 00 00 01 
        01 0A 00 00 00 00 02 00 00 02 
        01 0A 00 00 00 00 02 00 00 03   

===============================================
0002B0h   01 00 6E 00 00 00 00 00   ..n.....    structType: 0001, structLength: 
006E
0002B8h   00 40 0F 00 00 00 00 00   .@......
0002C0h   FF 4F 0F 00 00 00 00 00   ÿO......

        01 0A 00 00 00 00 02 02 00 00 
        01 0A 00 00 00 00 1C 07 00 00
        01 0A 00 00 00 00 1C 07 00 02
        01 08 00 00 00 00 1F 02 
        01 08 00 00 00 00 1F 05 
        01 0A 00 00 00 00 02 00 00 00   
        01 0A 00 00 00 00 02 00 00 01 
        01 0A 00 00 00 00 02 00 00 02 
        01 0A 00 00 00 00 02 00 00 03 

===============================================
                            01 00   ........    structType: 0001, structLength: 
006E
000320h   6E 00 00 00 00 00 00 80   n.......
000328h   0E 00 00 00 00 00 FF 8F   ......ÿ.
000330h   0E 00 00 00 00 00 

        01 0A 00 00 00 00 02 02 00 00   
        01 0A 00 00 00 00 1C 07 00 00 
        01 0A 00 00 00 00 1C 07 00 02 
        01 08 00 00 00 00 1F 02 
        01 08 00 00 00 00 1F 05 
        01 0A 00 00 00 00 02 00 00 00 
        01 0A 00 00 00 00 02 00 00 01   
        01 0A 00 00 00 00 02 00 00 02 
        01 0A 00 00 00 00 02 00 00 03

===============================================
                      02 00 60 00   ......`.    structType: 0002, structLength: 
0060
000390h   00 00 00 00                           Root Port ATS Capability 
Reporting (ATSR) Structure

        02 08 00 00 00 20 00 00 
        02 08 00 00 00 20 01 00 
        02 08 00 00 00 20 01 01 
        02 08 00 00 00 20 02 00 
        02 08 00 00 00 20 02 01 
        02 08 00 00 00 20 02 02 
        02 08 00 00 00 20 02 03 
        02 08 00 00 00 20 03 00 
        02 08 00 00 00 20 03 01 
        02 08 00 00 00 20 03 02 
        02 08 00 00 00 20 03 03 

===============================================
                      02 00 58 00   . ....X.    structType: 0002, structLength: 
0058
0003F0h   00 00 00 00                           Root Port ATS Capability 
Reporting (ATSR) Structure

        02 08 00 00 00 00 01 00 
        02 08 00 00 00 00 01 01 
        02 08 00 00 00 00 02 00 
        02 08 00 00 00 00 02 01
        02 08 00 00 00 00 02 02
        02 08 00 00 00 00 02 03 
        02 08 00 00 00 00 03 00
        02 08 00 00 00 00 03 01
        02 08 00 00 00 00 03 02 
        02 08 00 00 00 00 03 03 

                      D0            ....Ð


======================================================================================================



000000h   44 4D 41 52 44 04 00 00   DMARD...    length:00000444
000008h   01 69 48 50 20 20 20 20   .iHP    
000010h   50 72 6F 4C 69 61 6E 74   ProLiant
000018h   01 00 00 00 D2 04 00 00   ....Ò...
000020h   2E 16 00 00 2D 03 00 00   ....-...
000028h   00 00 00 00 00 00 00 00   ........

000030h   00 00 B0 00 00 00 00 00   ..°.....    structType: 0000 (DRHD), 
structLength: 00B0 flags: 00
000038h   00 E0 EF FB 00 00 00 00   .àïû....    base: FBEFE000  (dmar0)  buna 
uygun dmar_regions bulunuyor. units lere ekleniyor..

000040h   02 08 00 00 00 20 00 00   ..... ..    PCI Sub-hierarchy
000048h   02 08 00 00 00 20 01 00   ..... ..    PCI Sub-hierarchy
000050h   02 08 00 00 00 20 01 01   ..... ..    PCI Sub-hierarchy
000058h   02 08 00 00 00 20 02 00   ..... ..    PCI Sub-hierarchy
000060h   02 08 00 00 00 20 02 01   ..... ..    PCI Sub-hierarchy
000068h   02 08 00 00 00 20 02 02   ..... ..    PCI Sub-hierarchy
000070h   02 08 00 00 00 20 02 03   ..... ..    PCI Sub-hierarchy
000078h   02 08 00 00 00 20 03 00   ..... ..    PCI Sub-hierarchy
000080h   02 08 00 00 00 20 03 01   ..... ..    PCI Sub-hierarchy
000088h   02 08 00 00 00 20 03 02   ..... ..    PCI Sub-hierarchy
000090h   02 08 00 00 00 20 03 03   ..... ..    PCI Sub-hierarchy
000098h   03 08 00 00 0A 20 05 04   ..... ..    IOAPIC
0000A0h   01 08 00 00 00 20 04 00   ..... ..    PCI Endpoint Device
0000A8h   01 08 00 00 00 20 04 01   ..... ..    PCI Endpoint Device
0000B0h   01 08 00 00 00 20 04 02   ..... ..    PCI Endpoint Device
0000B8h   01 08 00 00 00 20 04 03   ..... ..    PCI Endpoint Device
0000C0h   01 08 00 00 00 20 04 04   ..... ..    PCI Endpoint Device
0000C8h   01 08 00 00 00 20 04 05   ..... ..    PCI Endpoint Device
0000D0h   01 08 00 00 00 20 04 06   ..... ..    PCI Endpoint Device
0000D8h   01 08 00 00 00 20 04 07   ..... ..    PCI Endpoint Device


0000E0h   00 00 28 00 01 00 00 00   ..(.....    structType: 0000 (DRHD), 
structLength: 0028 flags: 01
0000E8h   00 E0 FF F4 00 00 00 00   .àÿô....    base: F4FFE000 (dmar1) 

0000F0h   03 08 00 00 08 00 1E 01   ........    IOAPIC
0000F8h   03 08 00 00 00 00 05 04   ........    IOAPIC
000100h   04 08 00 00 00 00 1F 00   ........    MSI_CAPABLE_HPET


000108h   01 00 28 00 00 00 00 00   ..(.....    structType: 0001, structLength: 
0028
000110h   00 D0 FF BD 00 00 00 00   .Ðÿ½....
000118h   FF FF FF BD 00 00 00 00   ÿÿÿ½....
000120h   01 08 00 00 00 00 1D 00   ........    PCI Endpoint Device
000128h   01 08 00 00 00 00 1A 00   ........    PCI Endpoint Device

000130h   01 00 36 00 00 00 00 00   ..6.....    structType: 0001, structLength: 
0036
000138h   00 60 FF BD 00 00 00 00   .`ÿ½....
000140h   FF CF FF BD 00 00 00 00   ÿÏÿ½....

000148h   01 0A 00 00 00 00 1C 07   ........    PCI Endpoint Device (size A)
000150h   00 00 01 0A 00 00 00 00   ........    PCI Endpoint Device (size A)
000158h   1C 07 00 02 01 0A 00 00   ........    PCI Endpoint Device (size A)
000160h   00 00 1C 07 00 04 


                            01 00   ........    structType: 0001, structLength: 
006E                            
000168h   6E 00 00 00 00 00 00 30   n......0
000170h   F8 BD 00 00 00 00 FF 4F   ø½....ÿO
000178h   F8 BD 00 00 00 00 
                            01 0A   ø½......
000180h   00 00 00 00 02 02 00 00   ........
000188h   01 0A 00 00 00 00 1C 07   ........
000190h   00 00 01 0A 00 00 00 00   ........
000198h   1C 07 00 02 01 08 00 00   ........
0001A0h   00 00 1F 02 01 08 00 00   ........
0001A8h   00 00 1F 05 01 0A 00 00   ........
0001B0h   00 00 02 00 00 00 01 0A   ........
0001B8h   00 00 00 00 02 00 00 01   ........
0001C0h   01 0A 00 00 00 00 02 00   ........
0001C8h   00 02 01 0A 00 00 00 00   ........
0001D0h   02 00 00 03 

                      01 00 6E 00   ......n.    structType: 0001, structLength: 
006E
0001D8h   00 00 00 00 00 F0 F7 BD   .....ð÷½
0001E0h   00 00 00 00 FF 2F F8 BD   ....ÿ/ø½
0001E8h   00 00 00 00 01 0A 00 00   ........
0001F0h   00 00 02 02 00 00 01 0A   ........
0001F8h   00 00 00 00 1C 07 00 00   ........
000200h   01 0A 00 00 00 00 1C 07   ........
000208h   00 02 01 08 00 00 00 00   ........
000210h   1F 02 01 08 00 00 00 00   ........
000218h   1F 05 01 0A 00 00 00 00   ........
000220h   02 00 00 00 01 0A 00 00   ........
000228h   00 00 02 00 00 01 01 0A   ........
000230h   00 00 00 00 02 00 00 02   ........
000238h   01 0A 00 00 00 00 02 00   ........
000240h   00 03 

                01 00 6E 00 00 00   ....n...    structType: 0001, structLength: 
006E
000248h   00 00 00 F0 F6 BD 00 00   ...ðö½..
000250h   00 00 FF EF F7 BD 00 00   ..ÿï÷½..
000258h   00 00 01 0A 00 00 00 00   ........
000260h   02 02 00 00 01 0A 00 00   ........
000268h   00 00 1C 07 00 00 01 0A   ........
000270h   00 00 00 00 1C 07 00 02   ........
000278h   01 08 00 00 00 00 1F 02   ........
000280h   01 08 00 00 00 00 1F 05   ........
000288h   01 0A 00 00 00 00 02 00   ........
000290h   00 00 01 0A 00 00 00 00   ........
000298h   02 00 00 01 01 0A 00 00   ........
0002A0h   00 00 02 00 00 02 01 0A   ........
0002A8h   00 00 00 00 02 00 00 03   ........


0002B0h   01 00 6E 00 00 00 00 00   ..n.....    structType: 0001, structLength: 
006E
0002B8h   00 40 0F 00 00 00 00 00   .@......
0002C0h   FF 4F 0F 00 00 00 00 00   ÿO......
0002C8h   01 0A 00 00 00 00 02 02   ........
0002D0h   00 00 01 0A 00 00 00 00   ........
0002D8h   1C 07 00 00 01 0A 00 00   ........
0002E0h   00 00 1C 07 00 02 01 08   ........
0002E8h   00 00 00 00 1F 02 01 08   ........
0002F0h   00 00 00 00 1F 05 01 0A   ........
0002F8h   00 00 00 00 02 00 00 00   ........
000300h   01 0A 00 00 00 00 02 00   ........
000308h   00 01 01 0A 00 00 00 00   ........
000310h   02 00 00 02 01 0A 00 00   ........
000318h   00 00 02 00 00 03 

                            01 00   ........    structType: 0001, structLength: 
006E
000320h   6E 00 00 00 00 00 00 80   n.......
000328h   0E 00 00 00 00 00 FF 8F   ......ÿ.
000330h   0E 00 00 00 00 00 01 0A   ........
000338h   00 00 00 00 02 02 00 00   ........
000340h   01 0A 00 00 00 00 1C 07   ........
000348h   00 00 01 0A 00 00 00 00   ........
000350h   1C 07 00 02 01 08 00 00   ........
000358h   00 00 1F 02 01 08 00 00   ........
000360h   00 00 1F 05 01 0A 00 00   ........
000368h   00 00 02 00 00 00 01 0A   ........
000370h   00 00 00 00 02 00 00 01   ........
000378h   01 0A 00 00 00 00 02 00   ........
000380h   00 02 01 0A 00 00 00 00   ........
000388h   02 00 00 03 

                      02 00 60 00   ......`.    structType: 0002, structLength: 
0060
000390h   00 00 00 00 02 08 00 00   ........
000398h   00 20 00 00 02 08 00 00   . ......
0003A0h   00 20 01 00 02 08 00 00   . ......
0003A8h   00 20 01 01 02 08 00 00   . ......
0003B0h   00 20 02 00 02 08 00 00   . ......
0003B8h   00 20 02 01 02 08 00 00   . ......
0003C0h   00 20 02 02 02 08 00 00   . ......
0003C8h   00 20 02 03 02 08 00 00   . ......
0003D0h   00 20 03 00 02 08 00 00   . ......
0003D8h   00 20 03 01 02 08 00 00   . ......
0003E0h   00 20 03 02 02 08 00 00   . ......
0003E8h   00 20 03 03 

                      02 00 58 00   . ....X.    structType: 0002, structLength: 
0058
0003F0h   00 00 00 00 02 08 00 00   ........
0003F8h   00 00 01 00 02 08 00 00   ........
000400h   00 00 01 01 02 08 00 00   ........
000408h   00 00 02 00 02 08 00 00   ........
000410h   00 00 02 01 02 08 00 00   ........
000418h   00 00 02 02 02 08 00 00   ........
000420h   00 00 02 03 02 08 00 00   ........
000428h   00 00 03 00 02 08 00 00   ........
000430h   00 00 03 01 02 08 00 00   ........
000438h   00 00 03 02 02 08 00 00   ........
000440h   00 00 03 03 

                      D0            ....Ð

Reply via email to