Example #1
0
    def __init__(self, helper=None):
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid            = 0xFFFF
        self.did            = 0xFFFF
        self.code           = CHIPSET_CODE_UNKNOWN
        self.longname       = "Unrecognized Platform"
        self.id             = CHIPSET_ID_UNKNOWN
        self.pch_vid        = 0xFFFF
        self.pch_did        = 0xFFFF
        self.pch_code       = CHIPSET_CODE_UNKNOWN
        self.pch_longname   = 'Unrecognized PCH'
        self.pch_id         = CHIPSET_ID_UNKNOWN
        self.Cfg        = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci        = pci.Pci(self)
        self.mem        = physmem.Memory(self)
        self.msr        = msr.Msr(self)
        self.ucode      = ucode.Ucode(self)
        self.io         = io.PortIO(self)
        self.cpu        = cpu.CPU(self)
        self.msgbus     = msgbus.MsgBus(self)
        self.mmio       = mmio.MMIO(self)
        self.iobar      = iobar.IOBAR(self)
        self.igd        = igd.IGD(self)
Example #2
0
    def __init__(self, helper=None):
        if logger().VERBOSE: logger().log("[Chipset] __init__")
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid = 0
        self.did = 0
        self.code = CHIPSET_CODE_UNKNOWN
        self.longname = "Unrecognized Platform"
        self.id = CHIPSET_ID_UNKNOWN
        self.Cfg = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci = Pci(self)
        self.mem = Memory(self)
        self.msr = Msr(self)
        self.ucode = Ucode(self)
        self.io = PortIO(self)
        self.cr = CrRegs(self)
        self.cpuid = CpuID(self)
Example #3
0
    def __init__(self, helper=None):
        if logger().VERBOSE: logger().log("[Chipset] __init__")
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid        = 0
        self.did        = 0
        self.code       = CHIPSET_CODE_UNKNOWN
        self.longname   = "Unrecognized Platform"
        self.id         = CHIPSET_ID_UNKNOWN
        self.Cfg        = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci        = Pci      ( self )
        self.mem        = Memory   ( self )
        self.msr        = Msr      ( self )
        self.ucode      = Ucode    ( self )
        self.io         = PortIO   ( self )
        self.cr         = CrRegs   ( self )
        self.cpuid      = CpuID    ( self )
Example #4
0
    def __init__(self, helper=None):
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid        = 0xFFFF
        self.did        = 0xFFFF
        self.code       = CHIPSET_CODE_UNKNOWN
        self.longname   = "Unrecognized Platform"
        self.id         = CHIPSET_ID_UNKNOWN
        self.Cfg        = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci        = pci.Pci(self)
        self.mem        = physmem.Memory(self)
        self.msr        = msr.Msr(self)
        self.ucode      = ucode.Ucode(self)
        self.io         = io.PortIO(self)
        self.cpu        = cpu.CPU(self)
        self.msgbus     = msgbus.MsgBus(self)
        self.mmio       = mmio.MMIO(self)
        self.iobar      = iobar.IOBAR(self)
        self.igd        = igd.IGD(self)
Example #5
0
    def __init__(self, helper=None):
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid = 0
        self.did = 0
        self.code = CHIPSET_CODE_UNKNOWN
        self.longname = "Unrecognized Platform"
        self.id = CHIPSET_ID_UNKNOWN
        self.Cfg = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci = Pci(self)
        self.mem = Memory(self)
        self.msr = Msr(self)
        self.ucode = Ucode(self)
        self.io = PortIO(self)
        self.cpu = chipsec.hal.cpu.CPU(self)
        self.msgbus = MsgBus(self)
Example #6
0
    def __init__(self, helper=None):
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid        = 0
        self.did        = 0
        self.code       = ""
        self.longname   = "Unrecognized Platform"
        self.id         = CHIPSET_ID_UNKNOWN

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci    	= Pci      ( self.helper )
        self.mem    	= Memory   ( self.helper )
        self.msr    	= Msr      ( self.helper )
        self.ucode  	= Ucode    ( self.helper )
        self.io     	= PortIO   ( self.helper )
        self.cpuid      = CpuID    ( self.helper )
Example #7
0
    def __init__(self, helper=None):
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid        = 0
        self.did        = 0
        self.code       = CHIPSET_CODE_UNKNOWN
        self.longname   = "Unrecognized Platform"
        self.id         = CHIPSET_ID_UNKNOWN
        self.Cfg        = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci        = Pci      ( self )
        self.mem        = Memory   ( self )
        self.msr        = Msr      ( self )
        self.ucode      = Ucode    ( self )
        self.io         = PortIO   ( self )
        self.cpu        = chipsec.hal.cpu.CPU( self )
        self.msgbus     = MsgBus   ( self )
Example #8
0
class Chipset:

    def __init__(self, helper=None):
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid            = 0xFFFF
        self.did            = 0xFFFF
        self.code           = CHIPSET_CODE_UNKNOWN
        self.longname       = "Unrecognized Platform"
        self.id             = CHIPSET_ID_UNKNOWN
        self.pch_vid        = 0xFFFF
        self.pch_did        = 0xFFFF
        self.pch_code       = CHIPSET_CODE_UNKNOWN
        self.pch_longname   = 'Unrecognized PCH'
        self.pch_id         = CHIPSET_ID_UNKNOWN
        self.Cfg        = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci        = pci.Pci(self)
        self.mem        = physmem.Memory(self)
        self.msr        = msr.Msr(self)
        self.ucode      = ucode.Ucode(self)
        self.io         = io.PortIO(self)
        self.cpu        = cpu.CPU(self)
        self.msgbus     = msgbus.MsgBus(self)
        self.mmio       = mmio.MMIO(self)
        self.iobar      = iobar.IOBAR(self)
        self.igd        = igd.IGD(self)
        #
        # All HAL components which use above 'basic primitive' HAL components
        # should be instantiated in modules/utilcmd with an instance of chipset
        # Examples:
        # - initializing SPI HAL component in a module or util extension:
        #   self.spi = SPI( self.cs )
        #

    ##################################################################################
    #
    # Iitialization
    #
    ##################################################################################
    def detect_platform( self ):
        vid = 0xFFFF
        did = 0xFFFF
        pch_vid = 0xFFFF
        pch_did = 0xFFFF
        try:
            vid_did = self.pci.read_dword(0, 0, 0, 0)
            vid = vid_did & 0xFFFF
            did = (vid_did >> 16) & 0xFFFF
        except:
            if logger().DEBUG: logger().error("pci.read_dword couldn't read platform VID/DID")
        try:
            vid_did = self.pci.read_dword(0, 31, 0, 0)
            pch_vid = vid_did & 0xFFFF
            pch_did = (vid_did >> 16) & 0xFFFF
        except:
            if logger().DEBUG: logger().error("pci.read_dword couldn't read PCH VID/DID")
        return (vid, did, pch_vid, pch_did)

    def init( self, platform_code, req_pch_code, start_driver, driver_exists=False ):

        _unknown_platform = False
        self.helper.start(start_driver, driver_exists)
        logger().log( '[CHIPSEC] API mode: %s' % ('using OS native API (not using CHIPSEC kernel module)' if self.use_native_api() else 'using CHIPSEC kernel module API') )

        self.vid, self.did, self.pch_vid, self.pch_did = self.detect_platform()
        if platform_code is None:
            if VID_INTEL != self.vid:
                _unknown_platform = True
        else:
            self.vid = VID_INTEL
            if Chipset_Code.has_key( platform_code ):
                self.did = Chipset_Code[ platform_code ]
            else:
                _unknown_platform = True
                self.vid = 0xFFFF
                self.did = 0xFFFF

        if Chipset_Dictionary.has_key( self.did ):
            data_dict       = Chipset_Dictionary[ self.did ]
            self.code       = data_dict['code'].lower()
            self.longname   = data_dict['longname']
            self.id         = data_dict['id']
        else:
            _unknown_platform = True
            self.longname   = 'UnknownPlatform'

        if req_pch_code is not None:
            self.pch_vid = VID_INTEL
            if pch_codes.has_key(req_pch_code):
                self.pch_did = pch_codes[req_pch_code]
            else:
                self.pch_vid = 0xFFFF
                self.pch_did = 0xFFFF

        if self.pch_vid == VID_INTEL and pch_dictionary.has_key(self.pch_did):
            data_dict           = pch_dictionary[self.pch_did]
            self.pch_code       = data_dict['code'].lower()
            self.pch_longname   = data_dict['longname']
            self.pch_id         = data_dict['id']
        else:
            self.pch_longname = 'Default PCH'

        self.init_cfg()
        if _unknown_platform and start_driver:
            msg = 'Unsupported Platform: VID = 0x%04X, DID = 0x%04X' % (self.vid,self.did)
            logger().error( msg )
            raise UnknownChipsetError, msg


    def destroy( self, start_driver ):
        self.helper.stop( start_driver )

    def get_chipset_id(self):
        return self.id

    def get_pch_id(self):
        return self.pch_id

    def get_chipset_code(self):
        return self.code

    def get_pch_code(self):
        return self.pch_code

    def get_chipset_name(self, id):
        return self.longname

    def get_pch_name(self, id):
        return self.pch_longname

    def print_chipset(self):
        logger().log("[*] Platform: {}\n          VID: {:04X}\n          DID: {:04X}".format(self.longname, self.vid, self.did))

    def print_pch(self):
        logger().log("[*] PCH     : {}\n          VID: {:04X}\n          DID: {:04X}".format(self.pch_longname, self.pch_vid, self.pch_did))

    def is_core(self):
        return  self.get_chipset_id() in CHIPSET_FAMILY_CORE

    def is_server(self):
        return  self.get_chipset_id() in CHIPSET_FAMILY_XEON

    def is_atom(self):
        return self.get_chipset_id() in CHIPSET_FAMILY_ATOM

    def use_native_api(self):
        return self.helper.use_native_api()

    ##################################################################################
    #
    # Loading platform configuration from XML files in chipsec/cfg/
    #
    ##################################################################################

    def init_xml_configuration( self ):
        # Create a sorted config file list (xml only)
        _cfg_files = []
        _cfg_path = os.path.join( chipsec.file.get_main_dir(), 'chipsec/cfg' )
        for root, subdirs, files in os.walk(_cfg_path):
            _cfg_files.extend([os.path.join(root, x) for x in files if fnmatch.fnmatch(x, '*.xml')])
        _cfg_files.sort()
        if logger().VERBOSE:
            logger().log("[*] Configuration Files:")
            for _xml in _cfg_files:
                logger().log("[*] - {}".format(_xml))

        # Locate common (chipsec/cfg/common*.xml) configuration XML files.
        loaded_files = []
        for _xml in _cfg_files:
            if fnmatch.fnmatch(os.path.basename(_xml), 'common*.xml'):
                loaded_files.append(_xml)

        # Locate platform specific (chipsec/cfg/<code>*.xml) configuration XML files.
        if self.code and CHIPSET_CODE_UNKNOWN != self.code:
            for _xml in _cfg_files:
                if fnmatch.fnmatch(os.path.basename(_xml), '{}*.xml'.format(self.code)):
                    loaded_files.append(_xml)

        # Locate PCH specific (chipsec/cfg/pch_<code>*.xml) configuration XML files.
        if self.pch_code and CHIPSET_CODE_UNKNOWN != self.pch_code:
            for _xml in _cfg_files:
                if fnmatch.fnmatch(os.path.basename(_xml), '{}*.xml'.format(self.pch_code)):
                    loaded_files.append(_xml)

        # Locate configuration files from all other XML files recursively (if any) excluding other platform configuration files.
        platform_files = []
        for plat in [c.lower() for c in Chipset_Code]:
            platform_files.extend([x for x in _cfg_files if fnmatch.fnmatch(os.path.basename(x), '{}*.xml'.format(plat)) or os.path.basename(x).startswith(PCH_CODE_PREFIX.lower())])
        loaded_files.extend([x for x in _cfg_files if x not in loaded_files and x not in platform_files])

        # Load all configuration files for this platform.
        if logger().VERBOSE: logger().log("[*] Loading Configuration Files:")
        for _xml in loaded_files:
            self.init_cfg_xml(_xml, self.code, self.pch_code)
        self.Cfg.XML_CONFIG_LOADED = True


    def init_cfg_xml(self, fxml, code, pch_code):
        import xml.etree.ElementTree as ET
        if not os.path.exists( fxml ): return
        if logger().VERBOSE: logger().log( "[*] looking for platform config in '%s'.." % fxml )
        tree = ET.parse( fxml )
        root = tree.getroot()
        for _cfg in root.iter('configuration'):
            if 'platform' not in _cfg.attrib:
                if logger().HAL: logger().log( "[*] loading common platform config from '%s'.." % fxml )
            elif code == _cfg.attrib['platform'].lower():
                if logger().HAL: logger().log( "[*] loading '%s' platform config from '%s'.." % (code,fxml) )
            elif pch_code == _cfg.attrib['platform'].lower():
                if logger().HAL: logger().log("[*] loading '{}' PCH config from '{}'..".format(pch_code,fxml))
            else: continue

            if logger().VERBOSE: logger().log( "[*] loading integrated devices/controllers.." )
            for _pci in _cfg.iter('pci'):
                for _device in _pci.iter('device'):
                    _name = _device.attrib['name']
                    del _device.attrib['name']
                    if 'undef' in _device.attrib and _name in self.Cfg.CONFIG_PCI:
                        if logger().VERBOSE: logger().log("    - {:16}: {}".format(_name, _device.attrib['undef']))
                        self.Cfg.CONFIG_PCI.pop(_name, None)
                        continue
                    self.Cfg.CONFIG_PCI[ _name ] = _device.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _device.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading MMIO BARs.." )
            for _mmio in _cfg.iter('mmio'):
                for _bar in _mmio.iter('bar'):
                    _name = _bar.attrib['name']
                    del _bar.attrib['name']
                    if 'undef' in _bar.attrib and _name in self.Cfg.MMIO_BARS:
                        if logger().VERBOSE: logger().log("    - {:16}: {}".format(_name, _bar.attrib['undef']))
                        self.Cfg.MMIO_BARS.pop(_name, None)
                        continue
                    self.Cfg.MMIO_BARS[ _name ] = _bar.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _bar.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading I/O BARs.." )
            for _io in _cfg.iter('io'):
                for _bar in _io.iter('bar'):
                    _name = _bar.attrib['name']
                    del _bar.attrib['name']
                    if 'undef' in _bar.attrib and _name in self.Cfg.IO_BARS:
                        if logger().VERBOSE: logger().log("    - {:16}: {}".format(_name, _bar.attrib['undef']))
                        self.Cfg.IO_BARS.pop(_name, None)
                        continue
                    self.Cfg.IO_BARS[ _name ] = _bar.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _bar.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading memory ranges.." )
            for _memory in _cfg.iter('memory'):
                for _range in _memory.iter('range'):
                    _name = _range.attrib['name']
                    del _range.attrib['name']
                    if 'undef' in _range.attrib and _name in self.Cfg.MEMORY_RANGES:
                        if logger().VERBOSE: logger().log("    - {:16}: {}".format(_name, _range.attrib['undef']))
                        self.Cfg.MEMORY_RANGES.pop(_name, None)
                        continue
                    self.Cfg.MEMORY_RANGES[ _name ] = _range.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _range.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading configuration registers.." )
            for _registers in _cfg.iter('registers'):
                for _register in _registers.iter('register'):
                    _name = _register.attrib['name']
                    del _register.attrib['name']
                    if 'undef' in _register.attrib and _name in self.Cfg.REGISTERS:
                        if logger().VERBOSE: logger().log("    - {:16}: {}".format(_name, _register.attrib['undef']))
                        self.Cfg.REGISTERS.pop(_name, None)
                        continue
                    if 'size' not in _register.attrib: _register.attrib['size'] = "0x4"
                    if 'desc' not in _register.attrib: _register.attrib['desc'] = ''
                    reg_fields = {}
                    if _register.find('field') is not None:
                        for _field in _register.iter('field'):
                            _field_name = _field.attrib['name']
                            del _field.attrib['name']
                            if 'desc' not in _field.attrib: _field.attrib['desc'] = ''
                            reg_fields[ _field_name ] = _field.attrib
                        _register.attrib['FIELDS'] = reg_fields
                    self.Cfg.REGISTERS[ _name ] = _register.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _register.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading controls.." )
            for _controls in _cfg.iter('controls'):
                for _control in _controls.iter('control'):
                    _name = _control.attrib['name']
                    del _control.attrib['name']
                    if 'undef' in _control.attrib and _name in self.Cfg.CONTROLS:
                        if logger().VERBOSE: logger().log("    - {:16}: {}".format(_name, _control.attrib['undef']))
                        self.Cfg.CONTROLS.pop(_name, None)
                        continue
                    self.Cfg.CONTROLS[ _name ] = _control.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _control.attrib) )

    #
    # Load chipsec/cfg/<code>.py configuration file for platform <code>
    #
    def init_cfg(self):
        if self.code and '' != self.code:
            try:
                module_path = 'chipsec.cfg.' + self.code
                module = importlib.import_module( module_path )
                logger().log_good( "imported platform specific configuration: chipsec.cfg.%s" % self.code )
                self.Cfg = getattr( module, self.code )()
            except ImportError, msg:
                if logger().VERBOSE: logger().log( "[*] Couldn't import chipsec.cfg.%s\n%s" % ( self.code, str(msg) ) )

        #
        # Initialize platform configuration from XML files
        #
        try:
            self.init_xml_configuration()
        except:
            if logger().VERBOSE: logger().log_bad(traceback.format_exc())
            pass
Example #9
0
class Chipset:
    def __init__(self, helper=None):
        if logger().VERBOSE: logger().log("[Chipset] __init__")
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid = 0
        self.did = 0
        self.code = CHIPSET_CODE_UNKNOWN
        self.longname = "Unrecognized Platform"
        self.id = CHIPSET_ID_UNKNOWN
        self.Cfg = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci = Pci(self)
        self.mem = Memory(self)
        self.msr = Msr(self)
        self.ucode = Ucode(self)
        self.io = PortIO(self)
        self.cr = CrRegs(self)
        self.cpuid = CpuID(self)
        #
        # All HAL components which use above 'basic primitive' HAL components
        # should be instantiated in modules/utilcmd with an instance of chipset
        # Examples:
        # - initializing SPI HAL component in a module:
        #   self.spi = SPI( self.cs )
        # - initializing second order UEFI HAL component in utilcmd extension:
        #   spi = SPI( chipsec_util._cs )
        #

    def init(self, platform_code, start_svc):

        _unknown_platform = False
        if start_svc: self.helper.start()

        if platform_code is None:
            vid_did = self.pci.read_dword(0, 0, 0, 0)
            self.vid = vid_did & 0xFFFF
            self.did = (vid_did >> 16) & 0xFFFF
            if VID_INTEL != self.vid:
                _unknown_platform = True
        else:
            self.vid = VID_INTEL
            self.code = platform_code.lower()
            if Chipset_Code.has_key(platform_code):
                self.did = Chipset_Code[platform_code]
            else:
                _unknown_platform = True
                self.did = 0xFFFF

        if Chipset_Dictionary.has_key(self.did):
            data_dict = Chipset_Dictionary[self.did]
            self.code = data_dict['code'].lower()
            self.longname = data_dict['longname']
            self.id = data_dict['id']
        else:
            _unknown_platform = True
            self.longname = 'UnknownPlatform'

        self.init_cfg()
        if _unknown_platform:
            msg = 'Unsupported Platform: VID = 0x%04X, DID = 0x%04X' % (
                self.vid, self.did)
            logger().error(msg)
            raise UnknownChipsetError, msg

    def destroy(self, start_svc):
        self.stop(start_svc)
        #self.helper.destroy()

    def stop(self, start_svc):
        if start_svc: self.helper.stop()

    def get_chipset_id(self):
        return self.id

    def get_chipset_code(self):
        return self.code

    def get_chipset_name(self, id):
        return self.longname

    def print_chipset(self):
        logger().log(
            "[*] Platform: %s\n          VID: %04X\n          DID: %04X" %
            (self.longname, self.vid, self.did))

    ##################################################################################
    #
    # Loading platform configuration from XML files in chipsec/cfg/
    #
    ##################################################################################

    def init_xml_configuration(self):
        _cfg_path = os.path.join(chipsec.file.get_main_dir(), 'chipsec/cfg')
        # Load chipsec/cfg/common.xml configuration XML file common for all platforms if it exists
        self.init_cfg_xml(os.path.join(_cfg_path, 'common.xml'), self.code)
        # Load chipsec/cfg/<code>.xml configuration XML file if it exists for platform <code>
        if self.code and '' != self.code:
            self.init_cfg_xml(os.path.join(_cfg_path, ('%s.xml' % self.code)),
                              self.code)
        # Load configuration from all other XML files recursively (if any)
        for dirname, subdirs, xml_fnames in os.walk(_cfg_path):
            for _xml in xml_fnames:
                if fnmatch.fnmatch(_xml, '*.xml') and not fnmatch.fnmatch(
                        _xml, 'common.xml') and not (_xml in [
                            '%s.xml' % c.lower() for c in Chipset_Code
                        ]):
                    self.init_cfg_xml(os.path.join(dirname, _xml), self.code)
        self.Cfg.XML_CONFIG_LOADED = True

    def init_cfg_xml(self, fxml, code):
        import xml.etree.ElementTree as ET
        if not os.path.exists(fxml): return
        if logger().VERBOSE:
            logger().log("[*] looking for platform config in '%s'.." % fxml)
        tree = ET.parse(fxml)
        root = tree.getroot()
        for _cfg in root.iter('configuration'):
            if 'platform' not in _cfg.attrib:
                if logger().HAL:
                    logger().log(
                        "[*] loading common platform config from '%s'.." %
                        fxml)
            elif code == _cfg.attrib['platform'].lower():
                if logger().HAL:
                    logger().log(
                        "[*] loading '%s' platform config from '%s'.." %
                        (code, fxml))
            else:
                continue

            if logger().VERBOSE:
                logger().log("[*] loading integrated devices/controllers..")
            for _pci in _cfg.iter('pci'):
                for _device in _pci.iter('device'):
                    _name = _device.attrib['name']
                    del _device.attrib['name']
                    self.Cfg.CONFIG_PCI[_name] = _device.attrib
                    if logger().VERBOSE:
                        logger().log("    + %-16s: %s" %
                                     (_name, _device.attrib))
            if logger().VERBOSE: logger().log("[*] loading MMIO BARs..")
            for _mmio in _cfg.iter('mmio'):
                for _bar in _mmio.iter('bar'):
                    _name = _bar.attrib['name']
                    del _bar.attrib['name']
                    self.Cfg.MMIO_BARS[_name] = _bar.attrib
                    if logger().VERBOSE:
                        logger().log("    + %-16s: %s" % (_name, _bar.attrib))
            if logger().VERBOSE: logger().log("[*] loading I/O BARs..")
            for _io in _cfg.iter('io'):
                for _bar in _io.iter('bar'):
                    _name = _bar.attrib['name']
                    del _bar.attrib['name']
                    self.Cfg.IO_BARS[_name] = _bar.attrib
                    if logger().VERBOSE:
                        logger().log("    + %-16s: %s" % (_name, _bar.attrib))
            if logger().VERBOSE: logger().log("[*] loading memory ranges..")
            for _memory in _cfg.iter('memory'):
                for _range in _memory.iter('range'):
                    _name = _range.attrib['name']
                    del _range.attrib['name']
                    self.Cfg.MEMORY_RANGES[_name] = _range.attrib
                    if logger().VERBOSE:
                        logger().log("    + %-16s: %s" %
                                     (_name, _range.attrib))
            if logger().VERBOSE:
                logger().log("[*] loading configuration registers..")
            for _registers in _cfg.iter('registers'):
                for _register in _registers.iter('register'):
                    _name = _register.attrib['name']
                    del _register.attrib['name']
                    if 'size' not in _register.attrib:
                        _register.attrib['size'] = "0x4"
                    if 'desc' not in _register.attrib:
                        _register.attrib['desc'] = ''
                    reg_fields = {}
                    if _register.find('field') is not None:
                        for _field in _register.iter('field'):
                            _field_name = _field.attrib['name']
                            del _field.attrib['name']
                            if 'desc' not in _field.attrib:
                                _field.attrib['desc'] = ''
                            reg_fields[_field_name] = _field.attrib
                        _register.attrib['FIELDS'] = reg_fields
                    self.Cfg.REGISTERS[_name] = _register.attrib
                    if logger().VERBOSE:
                        logger().log("    + %-16s: %s" %
                                     (_name, _register.attrib))
            if logger().VERBOSE: logger().log("[*] loading controls..")
            for _controls in _cfg.iter('controls'):
                for _control in _controls.iter('control'):
                    _name = _control.attrib['name']
                    del _control.attrib['name']
                    self.Cfg.CONTROLS[_name] = _control.attrib
                    if logger().VERBOSE:
                        logger().log("    + %-16s: %s" %
                                     (_name, _control.attrib))

    #
    # Load chipsec/cfg/<code>.py configuration file for platform <code>
    #
    def init_cfg(self):
        if self.code and '' != self.code:
            try:
                module_path = 'chipsec.cfg.' + self.code
                module = importlib.import_module(module_path)
                logger().log_good(
                    "imported platform specific configuration: chipsec.cfg.%s"
                    % self.code)
                self.Cfg = getattr(module, self.code)()
            except ImportError, msg:
                if logger().VERBOSE:
                    logger().log("[*] Couldn't import chipsec.cfg.%s\n%s" %
                                 (self.code, str(msg)))

        #
        # Initialize platform configuration from XML files
        #
        try:
            self.init_xml_configuration()
        except:
            if logger().VERBOSE: logger().log_bad(traceback.format_exc())
            pass
Example #10
0
class Chipset:

    def __init__(self, helper=None):
        if logger().VERBOSE: logger().log("[Chipset] __init__")
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid        = 0
        self.did        = 0
        self.code       = CHIPSET_CODE_UNKNOWN
        self.longname   = "Unrecognized Platform"
        self.id         = CHIPSET_ID_UNKNOWN
        self.Cfg        = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci        = Pci      ( self )
        self.mem        = Memory   ( self )
        self.msr        = Msr      ( self )
        self.ucode      = Ucode    ( self )
        self.io         = PortIO   ( self )
        self.cr         = CrRegs   ( self )
        self.cpuid      = CpuID    ( self )
        #
        # All HAL components which use above 'basic primitive' HAL components
        # should be instantiated in modules/utilcmd with an instance of chipset
        # Examples:
        # - initializing SPI HAL component in a module:
        #   self.spi = SPI( self.cs )
        # - initializing second order UEFI HAL component in utilcmd extension:
        #   spi = SPI( chipsec_util._cs )
        #

    def init( self, platform_code, start_svc ):

        if start_svc: self.helper.start()

        if not platform_code:
            vid_did  = self.pci.read_dword( 0, 0, 0, 0 )
            self.vid = vid_did & 0xFFFF
            self.did = (vid_did >> 16) & 0xFFFF
            if VID_INTEL != self.vid: raise UnknownChipsetError, ('UnsupportedPlatform: Vendor ID = 0x%04X' % self.vid)
        else:
            if Chipset_Code.has_key( platform_code ): self.code = platform_code.lower()
            else: raise UnknownChipsetError, ('UnsupportedPlatform: code: %s' % platform_code)
            self.vid      = VID_INTEL
            self.did      = Chipset_Code[ platform_code ]

        if Chipset_Dictionary.has_key( self.did ):
            data_dict       = Chipset_Dictionary[ self.did ]
            self.code       = data_dict['code'].lower()
            self.longname   = data_dict['longname']
            self.id         = data_dict['id']
        else:
            raise UnknownChipsetError, ('UnsupportedPlatform: Device ID = 0x%04X' % self.did)
        self.init_cfg()

    def destroy( self, start_svc ):
        self.stop( start_svc )
        #self.helper.destroy()

    def stop( self, start_svc ):
        if start_svc: self.helper.stop()

    def get_chipset_id(self):
        return self.id

    def get_chipset_code(self):
        return self.code

    def get_chipset_name(self, id ):
        return self.longname

    def print_chipset(self):
        logger().log( "Platform: %s\n          VID: %04X\n          DID: %04X" % (self.longname, self.vid, self.did))


    ##################################################################################
    #
    # Loading platform configuration from XML files in chipsec/cfg/
    #
    ##################################################################################

    def init_xml_configuration( self ):
        _cfg_path = os.path.join( chipsec.file.get_main_dir(), 'chipsec/cfg' )
        # Load chipsec/cfg/common.xml configuration XML file common for all platforms if it exists
        self.init_cfg_xml( os.path.join(_cfg_path,'common.xml'), self.code )
        # Load chipsec/cfg/<code>.xml configuration XML file if it exists for platform <code>
        if self.code and '' != self.code:
            self.init_cfg_xml( os.path.join(_cfg_path,('%s.xml'%self.code)), self.code )
        # Load configuration from all other XML files recursively (if any)
        for dirname, subdirs, xml_fnames in os.walk( _cfg_path ):
            for _xml in xml_fnames:
                if fnmatch.fnmatch( _xml, '*.xml' ) and not fnmatch.fnmatch( _xml, 'common.xml' ) and not (_xml in ['%s.xml' % c.lower() for c in Chipset_Code]):
                    self.init_cfg_xml( os.path.join(dirname,_xml), self.code )
        self.Cfg.XML_CONFIG_LOADED = True


    def init_cfg_xml(self, fxml, code):
        import xml.etree.ElementTree as ET
        if not os.path.exists( fxml ): return
        if logger().VERBOSE: logger().log( "[*] looking for platform config in '%s'.." % fxml )
        tree = ET.parse( fxml )
        root = tree.getroot()
        for _cfg in root.iter('configuration'):
            if 'platform' not in _cfg.attrib:
                logger().log( "[*] loading common platform config from '%s'.." % fxml )
            elif code == _cfg.attrib['platform'].lower():
                logger().log( "[*] loading '%s' platform config from '%s'.." % (code,fxml) )
            else: continue

            if logger().VERBOSE: logger().log( "[*] loading integrated devices/controllers.." )
            for _pci in _cfg.iter('pci'):
                for _device in _pci.iter('device'):
                    _name = _device.attrib['name']
                    del _device.attrib['name']
                    self.Cfg.CONFIG_PCI[ _name ] = _device.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _device.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading MMIO BARs.." )
            for _mmio in _cfg.iter('mmio'):
                for _bar in _mmio.iter('bar'):
                    _name = _bar.attrib['name']
                    del _bar.attrib['name']
                    self.Cfg.MMIO_BARS[ _name ] = _bar.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _bar.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading I/O BARs.." )
            for _io in _cfg.iter('io'):
                for _bar in _io.iter('bar'):
                    _name = _bar.attrib['name']
                    del _bar.attrib['name']
                    self.Cfg.IO_BARS[ _name ] = _bar.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _bar.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading memory ranges.." )
            for _memory in _cfg.iter('memory'):
                for _range in _memory.iter('range'):
                    _name = _range.attrib['name']
                    del _range.attrib['name']
                    self.Cfg.MEMORY_RANGES[ _name ] = _range.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _range.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading configuration registers.." )
            for _registers in _cfg.iter('registers'):
                for _register in _registers.iter('register'):
                    _name = _register.attrib['name']
                    del _register.attrib['name']
                    if 'size' not in _register.attrib: _register.attrib['size'] = "0x4"
                    if 'desc' not in _register.attrib: _register.attrib['desc'] = ''
                    reg_fields = {}
                    if _register.find('field') is not None:
                        for _field in _register.iter('field'):
                            _field_name = _field.attrib['name']
                            del _field.attrib['name']
                            if 'desc' not in _field.attrib: _field.attrib['desc'] = ''
                            reg_fields[ _field_name ] = _field.attrib
                        _register.attrib['FIELDS'] = reg_fields
                    self.Cfg.REGISTERS[ _name ] = _register.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _register.attrib) )

    #
    # Load chipsec/cfg/<code>.py configuration file for platform <code>
    #
    def init_cfg(self):
        if self.code and '' != self.code:
            try:
                module_path = 'chipsec.cfg.' + self.code
                module = importlib.import_module( module_path )
                logger().log_good( "imported platform specific configuration: chipsec.cfg.%s" % self.code )
                self.Cfg = getattr( module, self.code )()
            except ImportError, msg:
                if logger().VERBOSE: logger().log( "[*] Couldn't import chipsec.cfg.%s\n%s" % ( self.code, str(msg) ) )

        #
        # Initialize platform configuration from XML files
        #
        try:
            self.init_xml_configuration()
        except:
            if logger().VERBOSE: logger().log_bad(traceback.format_exc())
            pass
Example #11
0
class Chipset:

    def __init__(self, helper=None):
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.init_xml_configuration()

        self.vid            = 0xFFFF
        self.did            = 0xFFFF
        self.rid            = 0xFF
        self.code           = CHIPSET_CODE_UNKNOWN
        self.longname       = "Unrecognized Platform"
        self.id             = CHIPSET_ID_UNKNOWN
        self.pch_vid        = 0xFFFF
        self.pch_did        = 0xFFFF
        self.pch_rid        = 0xFF
        self.pch_code       = CHIPSET_CODE_UNKNOWN
        self.pch_longname   = 'Unrecognized PCH'
        self.pch_id         = CHIPSET_ID_UNKNOWN
        self.Cfg        = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci        = pci.Pci(self)
        self.mem        = physmem.Memory(self)
        self.msr        = msr.Msr(self)
        self.ucode      = ucode.Ucode(self)
        self.io         = io.PortIO(self)
        self.cpu        = cpu.CPU(self)
        self.msgbus     = msgbus.MsgBus(self)
        self.mmio       = mmio.MMIO(self)
        self.iobar      = iobar.IOBAR(self)
        self.igd        = igd.IGD(self)
        #
        # All HAL components which use above 'basic primitive' HAL components
        # should be instantiated in modules/utilcmd with an instance of chipset
        # Examples:
        # - initializing SPI HAL component in a module or util extension:
        #   self.spi = SPI( self.cs )
        #

    ##################################################################################
    #
    # Initialization
    #
    ##################################################################################
    def detect_platform( self ):
        vid = 0xFFFF
        did = 0xFFFF
        rid = 0xFF
        pch_vid = 0xFFFF
        pch_did = 0xFFFF
        pch_rid = 0xFF
        try:
            vid_did = self.pci.read_dword(0, 0, 0, 0)
            vid = vid_did & 0xFFFF
            did = (vid_did >> 16) & 0xFFFF
            rid = self.pci.read_byte(0, 0, 0, PCI_HDR_RID_OFF)
        except:
            if logger().DEBUG: logger().error("pci.read_dword couldn't read platform VID/DID")
        try:
            vid_did = self.pci.read_dword(0, 31, 0, 0)
            pch_vid = vid_did & 0xFFFF
            pch_did = (vid_did >> 16) & 0xFFFF
            pch_rid = self.pci.read_byte(0, 31, 0, PCI_HDR_RID_OFF)
        except:
            if logger().DEBUG: logger().error("pci.read_dword couldn't read PCH VID/DID")
        return (vid, did, rid, pch_vid, pch_did, pch_rid)

    def get_cpuid(self):
            # Get processor version information
            (eax, ebx, ecx, edx) = self.cpu.cpuid(0x01, 0x00)
            stepping = eax & 0xF
            model = (eax >> 4) & 0xF
            extmodel = (eax >> 16) & 0xF
            family = (eax >> 8) & 0xF
            ptype = (eax >>12) & 0x3
            extfamily = (eax >> 20) & 0xFF
            ret = '{:01X}{:01X}{:01X}{:01X}{:01X}'.format(extmodel,ptype,family,model,stepping)
            if extfamily == 0:
                return ret
            else:
                return '{:02X}{}'.format(extfamily,ret)

    def init( self, platform_code, req_pch_code, start_driver, driver_exists=None, to_file=None, from_file=None ):
        _unknown_platform = False
        self.reqs_pch = False
        self.helper.start(start_driver, driver_exists, to_file, from_file)
        logger().log( '[CHIPSEC] API mode: {}'.format('using OS native API (not using CHIPSEC kernel module)' if self.use_native_api() else 'using CHIPSEC kernel module API') )

        vid, did, rid, pch_vid, pch_did, pch_rid = self.detect_platform()
        cpuid = self.get_cpuid()

        #initalize chipset values to unknown
        _unknown_platform = True
        self.longname   = 'UnknownPlatform'
        self.vid = 0xFFFF
        self.did = 0xFFFF
        self.rid = 0xFF
        #initialize pch values to unknown/default
        _unknown_pch = True
        self.pch_longname = 'Default PCH'
        self.pch_vid = 0xFFFF
        self.pch_did = 0xFFFF
        self.pch_rid = 0xFF

        if platform_code is None:
            #platform code was not passed in try to determine based upon cpu id
            if did in self.chipset_dictionary[vid] and len(self.chipset_dictionary[vid][did]) > 1 and cpuid in self.detection_dictionary.keys():
                for item in self.chipset_dictionary[vid][did]:
                    if self.detection_dictionary[cpuid] == item['code']:
                        #matched processor with detection value
                        _unknown_platform = False
                        data_dict       = item
                        self.code       = data_dict['code'].upper()
                        self.longname   = data_dict['longname']
                        self.vid = vid
                        self.did = did
                        self.rid = rid
                        break
            elif did in self.chipset_dictionary[vid]:
                _unknown_platform = False
                data_dict       = self.chipset_dictionary[vid][ did ][0]
                self.code       = data_dict['code'].upper()
                self.longname   = data_dict['longname']
                self.vid = vid
                self.did = did
                self.rid = rid
            elif cpuid in self.detection_dictionary.keys():
                _unknown_platform = False
                self.code       = self.detection_dictionary[cpuid]
                self.longname   = self.detection_dictionary[cpuid]
                self.vid = vid
                self.did = did
                self.rid = rid

        elif platform_code in self.chipset_codes:
            # Check if platform code passed in is valid and override configuraiton
            _unknown_platform = False
            self.vid = self.chipset_codes[ platform_code ]['vid']
            self.did = self.chipset_codes[ platform_code ]['did']
            self.rid = 0x00
            self.code = platform_code
            self.longname = platform_code

        if req_pch_code is not None:
            # Check if pch code passed in is valid
            if req_pch_code in self.pch_codes:
                self.pch_vid = self.pch_codes[req_pch_code]['vid']
                self.pch_did = self.pch_codes[req_pch_code]['did']
                self.pch_rid = 0x00
                self.pch_code = req_pch_code
                self.pch_longname = req_pch_code
                _unknown_pch = False
        elif pch_vid in self.pch_dictionary.keys() and pch_did in self.pch_dictionary[pch_vid].keys():
            #Check if pch did for device 0:31:0 is in configuration
            self.pch_vid = pch_vid
            self.pch_did = pch_did
            self.pch_rid = pch_rid
            data_dict           = self.pch_dictionary[self.pch_vid][self.pch_did][0]
            self.pch_code       = data_dict['code']
            self.pch_longname   = data_dict['longname']
            _unknown_pch = False

        if _unknown_platform and start_driver:
            msg = 'Unsupported Platform: VID = 0x{:04X}, DID = 0x{:04X}, RID = 0x{:02X}'.format(vid, did, rid)
            logger().error( msg )
            raise UnknownChipsetError (msg)
        if not _unknown_platform: # don't intialize config if platform is unknown
            self.init_cfg()
        if self.reqs_pch and _unknown_pch and start_driver:
            msg = 'Chipset requires a supported PCH to be loaded: VID = 0x{:04X}, DID = 0x{:04X}, RID = 0x{:02X}'.format(pch_vid, pch_did, pch_rid)
            logger().error( msg )
            raise UnknownChipsetError (msg)

    def destroy( self, start_driver ):
        self.helper.stop( start_driver )

    def get_chipset_code(self):
        return self.code

    def get_pch_code(self):
        return self.pch_code

    def get_chipset_name(self, id):
        return self.longname

    def get_pch_name(self, id):
        return self.pch_longname

    def print_chipset(self):
        logger().log("[*] Platform: {}\n          VID: {:04X}\n          DID: {:04X}\n          RID: {:02X}".format(self.longname, self.vid, self.did, self.rid))

    def print_pch(self):
        logger().log("[*] PCH     : {}\n          VID: {:04X}\n          DID: {:04X}\n          RID: {:02X}".format(self.pch_longname, self.pch_vid, self.pch_did, self.pch_rid))

    def is_core(self):
        return  self.get_chipset_code() in CHIPSET_FAMILY_CORE

    def is_server(self):
        return  self.get_chipset_code() in CHIPSET_FAMILY_XEON

    def is_atom(self):
        return self.get_chipset_code() in CHIPSET_FAMILY_ATOM

    def use_native_api(self):
        return self.helper.use_native_api()

    def print_supported_chipsets(self):
        logger().log( "\nSupported platforms:\n" )
        logger().log( "VID     | DID     | Name           | Code   | Long Name" )
        logger().log( "-------------------------------------------------------------------------------------" )
        for _vid in sorted(self.chipset_dictionary.keys()):
            for _did in sorted(self.chipset_dictionary[_vid]):
                for item in self.chipset_dictionary[_vid][_did]:
                    logger().log( " {:-#06x} | {:-#06x} | {:14} | {:6} | {:40}".format(_vid, _did, item['name'], item['code'].lower(), item['longname']) )

    ##################################################################################
    #
    # Loading platform configuration from XML files in chipsec/cfg/
    #
    ##################################################################################

    def init_xml_configuration(self):
        self.pch_dictionary = dict()
        self.chipset_dictionary = dict()
        self.device_dictionary = dict()
        self.chipset_codes = {}
        self.pch_codes = {}
        self.device_code = []
        self.load_list = []
        self.detection_dictionary = dict()

        # find VID
        _cfg_path = os.path.join( chipsec.file.get_main_dir(), 'chipsec', 'cfg' )
        VID = [f for f in os.listdir(_cfg_path) if os.path.isdir(os.path.join(_cfg_path, f)) and is_hex(f) ]
        # create dictionaries
        for vid in VID:
            self.chipset_dictionary[int(vid,16)] = collections.defaultdict(list)
            self.pch_dictionary[int(vid,16)] = collections.defaultdict(list)
            self.device_dictionary[int(vid,16)] = collections.defaultdict(list)
            for fxml in os.listdir(os.path.join(_cfg_path,vid)):
                if logger().DEBUG: logger().log( "[*] looking for platform config in '{}'..".format(fxml) )
                tree = ET.parse( os.path.join(_cfg_path,vid,fxml) )
                root = tree.getroot()
                for _cfg in root.iter('configuration'):
                    if 'platform' not in _cfg.attrib:
                        if logger().DEBUG: logger().log( "[*] found common platform config '{}'..".format(fxml) )
                        self.load_list.append(fxml)
                        continue
                    elif _cfg.attrib['platform'].lower().startswith('pch'):
                        if logger().DEBUG: logger().log( "[*] found PCH config at '{}'..".format(fxml) )
                        if not _cfg.attrib['platform'].upper() in self.pch_codes.keys():
                            self.pch_codes[_cfg.attrib['platform'].upper()] = {}
                            self.pch_codes[_cfg.attrib['platform'].upper()]['vid'] = int(vid,16)
                        mdict = self.pch_dictionary[int(vid,16)]
                        cdict = self.pch_codes[_cfg.attrib['platform'].upper()]
                    elif _cfg.attrib['platform'].upper():
                        if logger().DEBUG: logger().log("[*] found platform config from '{}'..".format(fxml))
                        if not _cfg.attrib['platform'].upper() in self.chipset_codes.keys():
                            self.chipset_codes[_cfg.attrib['platform'].upper()] = {}
                            self.chipset_codes[_cfg.attrib['platform'].upper()]['vid'] = int(vid,16)
                        mdict = self.chipset_dictionary[int(vid,16)]
                        cdict = self.chipset_codes[_cfg.attrib['platform'].upper()]
                    else:
                        continue
                    if logger().DEBUG: logger().log( "[*] Populating configuration dictionary.." )
                    for _info in _cfg.iter('info'):
                        if 'family' in _info.attrib:
                            if _info.attrib['family'].lower() == "core":
                                CHIPSET_FAMILY_CORE.append(_cfg.attrib['platform'].upper())
                            if _info.attrib['family'].lower() == "atom":
                                CHIPSET_FAMILY_ATOM.append(_cfg.attrib['platform'].upper())
                            if _info.attrib['family'].lower() == "xeon":
                                CHIPSET_FAMILY_XEON.append(_cfg.attrib['platform'].upper())
                            if _info.attrib['family'].lower() == "quark":
                                CHIPSET_FAMILY_QUARK.append(_cfg.attrib['platform'].upper())
                        if 'detection_value' in _info.attrib:
                            for dv in list(_info.attrib['detection_value'].split(',')):
                                self.detection_dictionary[dv.strip()] = _cfg.attrib['platform'].upper()
                        if _info.iter('sku'):
                            for _sku in _info.iter('sku'):
                                _det = ""
                                _did = int(_sku.attrib['did'],16)
                                del _sku.attrib['did']
                                mdict[_did].append(_sku.attrib)
                                if "detection_value" in _sku.attrib.keys():
                                    _det = _sku.attrib['detection_value']
                            cdict['did'] = _did
                            cdict['detection_value'] = _det
            for cc in self.chipset_codes:
                globals()["CHIPSET_CODE_{}".format(cc.upper())] = cc.upper()
            for pc in self.pch_codes:
                globals()["PCH_CODE_{}".format(pc[4:].upper())] = pc.upper()


    def load_xml_configuration( self ):
        # Create a sorted config file list (xml only)
        _cfg_files = []
        _cfg_path = os.path.join( chipsec.file.get_main_dir(), 'chipsec/cfg' )
        for root, subdirs, files in os.walk(_cfg_path):
            _cfg_files.extend([os.path.join(root, x) for x in files if fnmatch.fnmatch(x, '*.xml')])
        _cfg_files.sort()
        if logger().DEBUG:
            logger().log("[*] Configuration Files:")
            for _xml in _cfg_files:
                logger().log("[*] - {}".format(_xml))

        # Locate common (chipsec/cfg/common*.xml) configuration XML files.
        loaded_files = []
        if LOAD_COMMON:
            for _xml in _cfg_files:
                if fnmatch.fnmatch(os.path.basename(_xml), 'common*.xml'):
                    loaded_files.append(_xml)

        # Locate configuration files from all other XML files recursively (if any) excluding other platform configuration files.
            platform_files = []
            for plat in [c.lower() for c in self.chipset_codes]:
                platform_files.extend([x for x in _cfg_files if fnmatch.fnmatch(os.path.basename(x), '{}*.xml'.format(plat)) or os.path.basename(x).startswith(PCH_CODE_PREFIX.lower())])
            loaded_files.extend([x for x in _cfg_files if x not in loaded_files and x not in platform_files])

        # Locate platform specific (chipsec/cfg/<code>*.xml) configuration XML files.
        if self.code and CHIPSET_CODE_UNKNOWN != self.code:
            for _xml in _cfg_files:
                if fnmatch.fnmatch(os.path.basename(_xml), '{}*.xml'.format(self.code.lower())):
                    loaded_files.append(_xml)

        # Locate PCH specific (chipsec/cfg/pch_<code>*.xml) configuration XML files.
        if self.pch_code and CHIPSET_CODE_UNKNOWN != self.pch_code:
            for _xml in _cfg_files:
                if fnmatch.fnmatch(os.path.basename(_xml), '{}*.xml'.format(self.pch_code.lower())):
                    loaded_files.append(_xml)

        # Load all configuration files for this platform.
        if logger().DEBUG: logger().log("[*] Loading Configuration Files:")
        for _xml in loaded_files:
            self.init_cfg_xml(_xml, self.code.lower(), self.pch_code.lower())

        # Load Bus numbers for this platform.
        if logger().DEBUG: logger().log("[*] Discovering Bus Configuration:")
        self.init_cfg_bus()

        self.Cfg.XML_CONFIG_LOADED = True


    def init_cfg_xml(self, fxml, code, pch_code):
        if not os.path.exists( fxml ): return
        if logger().DEBUG: logger().log( "[*] looking for platform config in '{}'..".format(fxml) )
        tree = ET.parse( fxml )
        root = tree.getroot()
        for _cfg in root.iter('configuration'):
            if 'platform' not in _cfg.attrib:
                if logger().DEBUG: logger().log( "[*] loading common platform config from '{}'..".format(fxml) )
            elif code == _cfg.attrib['platform'].lower():
                if logger().DEBUG: logger().log( "[*] loading '{}' platform config from '{}'..".format(code,fxml) )
                if 'req_pch' in _cfg.attrib:
                    if 'true' == _cfg.attrib['req_pch'].lower():
                        self.reqs_pch = True
            elif pch_code == _cfg.attrib['platform'].lower():
                if logger().DEBUG: logger().log("[*] loading '{}' PCH config from '{}'..".format(pch_code,fxml))
            else: continue

            if logger().DEBUG: logger().log( "[*] loading integrated devices/controllers.." )
            for _pci in _cfg.iter('pci'):
                for _device in _pci.iter('device'):
                    _name = _device.attrib['name']
                    del _device.attrib['name']
                    if 'undef' in _device.attrib:
                        if _name in self.Cfg.CONFIG_PCI:
                            if logger().DEBUG: logger().log("    - {:16}: {}".format(_name, _device.attrib['undef']))
                            self.Cfg.CONFIG_PCI.pop(_name, None)
                        continue
                    self.Cfg.CONFIG_PCI[ _name ] = _device.attrib
                    if logger().DEBUG: logger().log( "    + {:16}: {}".format(_name, _device.attrib) )
            if logger().DEBUG: logger().log( "[*] loading MMIO BARs.." )
            for _mmio in _cfg.iter('mmio'):
                for _bar in _mmio.iter('bar'):
                    _name = _bar.attrib['name']
                    del _bar.attrib['name']
                    if 'undef' in _bar.attrib:
                        if _name in self.Cfg.MMIO_BARS:
                            if logger().DEBUG: logger().log("    - {:16}: {}".format(_name, _bar.attrib['undef']))
                            self.Cfg.MMIO_BARS.pop(_name, None)
                        continue
                    self.Cfg.MMIO_BARS[ _name ] = _bar.attrib
                    if logger().DEBUG: logger().log( "    + {:16}: {}".format(_name, _bar.attrib) )
            if logger().DEBUG: logger().log( "[*] loading I/O BARs.." )
            for _io in _cfg.iter('io'):
                for _bar in _io.iter('bar'):
                    _name = _bar.attrib['name']
                    del _bar.attrib['name']
                    if 'undef' in _bar.attrib:
                        if _name in self.Cfg.IO_BARS:
                            if logger().DEBUG: logger().log("    - {:16}: {}".format(_name, _bar.attrib['undef']))
                            self.Cfg.IO_BARS.pop(_name, None)
                        continue
                    self.Cfg.IO_BARS[ _name ] = _bar.attrib
                    if logger().DEBUG: logger().log( "    + {:16}: {}".format(_name, _bar.attrib) )
            if logger().DEBUG: logger().log( "[*] loading memory ranges.." )
            for _memory in _cfg.iter('memory'):
                for _range in _memory.iter('range'):
                    _name = _range.attrib['name']
                    del _range.attrib['name']
                    if 'undef' in _range.attrib:
                        if _name in self.Cfg.MEMORY_RANGES:
                            if logger().DEBUG: logger().log("    - {:16}: {}".format(_name, _range.attrib['undef']))
                            self.Cfg.MEMORY_RANGES.pop(_name, None)
                        continue
                    self.Cfg.MEMORY_RANGES[ _name ] = _range.attrib
                    if logger().DEBUG: logger().log( "    + {:16}: {}".format(_name, _range.attrib) )
            if logger().DEBUG: logger().log( "[*] loading configuration registers.." )
            for _registers in _cfg.iter('registers'):
                for _register in _registers.iter('register'):
                    _name = _register.attrib['name']
                    del _register.attrib['name']
                    if 'undef' in _register.attrib:
                        if _name in self.Cfg.REGISTERS:
                            if logger().DEBUG: logger().log("    - {:16}: {}".format(_name, _register.attrib['undef']))
                            self.Cfg.REGISTERS.pop(_name, None)
                        continue
                    if 'size' not in _register.attrib: _register.attrib['size'] = "0x4"
                    if 'desc' not in _register.attrib: _register.attrib['desc'] = ''
                    reg_fields = {}
                    if _register.find('field') is not None:
                        for _field in _register.iter('field'):
                            _field_name = _field.attrib['name']
                            del _field.attrib['name']
                            if 'desc' not in _field.attrib: _field.attrib['desc'] = ''
                            reg_fields[ _field_name ] = _field.attrib
                        _register.attrib['FIELDS'] = reg_fields
                    self.Cfg.REGISTERS[ _name ] = _register.attrib
                    if logger().DEBUG: logger().log( "    + {:16}: {}".format(_name, _register.attrib) )
            if logger().DEBUG: logger().log( "[*] loading controls.." )
            for _controls in _cfg.iter('controls'):
                for _control in _controls.iter('control'):
                    _name = _control.attrib['name']
                    del _control.attrib['name']
                    if 'undef' in _control.attrib:
                        if _name in self.Cfg.CONTROLS:
                            if logger().DEBUG: logger().log("    - {:16}: {}".format(_name, _control.attrib['undef']))
                            self.Cfg.CONTROLS.pop(_name, None)
                        continue
                    self.Cfg.CONTROLS[ _name ] = _control.attrib
                    if logger().DEBUG: logger().log( "    + {:16}: {}".format(_name, _control.attrib) )

    def init_cfg_bus( self ):
        if logger().DEBUG: logger().log( '[*] loading device buses..' )
        if QUIET_PCI_ENUM:
            old_hal_state = logger().HAL
            logger().HAL = False
        try:
            enum_devices = self.pci.enumerate_devices()
        except:
            if logger().DEBUG: logger().log('[*] Unable to enumerate PCI devices.')
            enum_devices = []
        if QUIET_PCI_ENUM:
            logger().HAL = old_hal_state
        for config_device in self.Cfg.CONFIG_PCI:
            device_data = self.Cfg.CONFIG_PCI[config_device]
            xml_vid  = device_data.get( 'vid', None )
            xml_did  = device_data.get( 'did', None )
            if (xml_vid and xml_did):
                bus_list = []
                did_list = [int(_,16) for _ in xml_did.split(',')]
                for enum_dev in enum_devices:
                    if ((int(device_data['dev'],16), int(device_data['fun'],16), int(xml_vid,16)) == enum_dev[1:4]) and (enum_dev[4] in did_list):
                        bus_list.append( hex(enum_dev[0]) )
                        if logger().DEBUG: logger().log( '    + {:16s}: VID 0x{:04X} - DID 0x{:04X} -> Bus 0x{:02X}'.format(config_device, enum_dev[3], enum_dev[4], enum_dev[0]) )
                if len(bus_list):
                    self.Cfg.BUS[ config_device ] = bus_list

    #
    # Load chipsec/cfg/<code>.py configuration file for platform <code>
    #
    def init_cfg(self):
        if self.code and '' != self.code:
            try:
                module_path = 'chipsec.cfg.' + self.code
                module = importlib.import_module( module_path )
                logger().log_good( "imported platform specific configuration: chipsec.cfg.{}".format(self.code) )
                self.Cfg = getattr( module, self.code )()
            except ImportError as msg:
                if logger().DEBUG: logger().log( "[*] Couldn't import chipsec.cfg.{}\n{}".format( self.code, str(msg) ) )

        #
        # Initialize platform configuration from XML files
        #
        try:
            self.load_xml_configuration()
        except:
            if logger().DEBUG: logger().log_bad(traceback.format_exc())
            pass


    ##################################################################################
    #
    # Functions which access configuration of integrated PCI devices (interfaces, controllers)
    # by device name (defined in XML configuration files)
    #
    ##################################################################################

    def get_device_BDF( self, device_name ):
        device = self.Cfg.CONFIG_PCI[ device_name ]
        if device is None or device == {}: raise DeviceNotFoundError ('DeviceNotFound: {}'.format(device_name))
        b = int(device['bus'],16)
        d = int(device['dev'],16)
        f = int(device['fun'],16)
        return (b,d,f)

    def get_DeviceVendorID( self, device_name ):
        (b,d,f) = self.get_device_BDF( device_name )
        return self.pci.get_DIDVID( b, d, f )

    def is_device_enabled( self, device_name ):
        if self.is_device_defined( device_name ):
            (b,d,f) = self.get_device_BDF( device_name )
            return self.pci.is_enabled( b, d, f )
        return False

    def is_register_device_enabled( self, reg_name, bus_index=0 ):
        if reg_name in self.Cfg.REGISTERS:
            reg = self.get_register_def( reg_name, bus_index )
            rtype = reg['type']
            if (rtype == RegisterType.MMCFG) or (rtype == RegisterType.PCICFG):
                b = int(reg['bus'], 16)
                d = int(reg['dev'], 16)
                f = int(reg['fun'], 16)
                return self.pci.is_enabled( b, d, f )
        return False

    def switch_device_def( self, target_dev, source_dev ):
        (b,d,f) = self.get_device_BDF( source_dev )
        self.Cfg.CONFIG_PCI[ target_dev ]['bus'] = str(b)
        self.Cfg.CONFIG_PCI[ target_dev ]['dev'] = str(d)
        self.Cfg.CONFIG_PCI[ target_dev ]['fun'] = str(f)

##################################################################################
#
# Main functionality to read/write configuration registers
# based on their XML configuration
#
# is_register_defined
#   checks if register is defined in the XML config
# is_device_defined
#   checks if device is defined in the XML config
# get_register_bus/get_device_bus
#   returns list of buses device/register was discovered on
# read_register/write_register
#   reads/writes configuration register (by name)
# read_register_all/write_register_all/write_register_all_single
#   reads/writes all configuration register instances (by name)
# get_register_field (set_register_field)
#   reads/writes the value of the field (by name) of configuration register (by register value)
# get_register_field_all (set_register_field_all)
#   reads/writes the value of the field (by name) of all configuration register instances (by register value)
# read_register_field (write_register_field)
#   reads/writes the value of the field (by name) of configuration register (by register name)
# read_register_field_all (write_register_field_all)
#   reads/writes the value of the field (by name) of all configuration register instances (by register name)
# register_has_field
#   checks if the register has specific field
# print_register
#   prints configuration register
# print_register_all
#   prints all configuration register instances
# get_control/set_control
#   reads/writes some control field (by name)
# is_all_value
#   checks if all elements in a list equal a given value
#
##################################################################################


    def is_register_defined(self, reg_name):
        try:
            return (self.Cfg.REGISTERS[reg_name] is not None)
        except KeyError:
            return False

    def is_device_defined(self, dev_name):
        if self.Cfg.CONFIG_PCI.get( dev_name, None ) is None:
            return False
        else:
            return True

    def get_register_def(self, reg_name, bus_index=0):
        reg_def = self.Cfg.REGISTERS[reg_name]
        if "device" in reg_def:
            dev_name = reg_def["device"]
            if reg_def["type"] == "pcicfg" or reg_def["type"] == "mmcfg":
                if dev_name in self.Cfg.CONFIG_PCI:
                    dev = self.Cfg.CONFIG_PCI[dev_name]
                    reg_def['bus'] = dev['bus']
                    reg_def['dev'] = dev['dev']
                    reg_def['fun'] = dev['fun']
                    if dev_name in self.Cfg.BUS:
                        if bus_index < len(self.Cfg.BUS[dev_name]):
                            reg_def['bus'] = self.Cfg.BUS[dev_name][bus_index]
                        else:
                            logger().error( "Bus index {:d} for '{}' not found.".format(bus_index, dev_name) )
            elif reg_def["type"] == "memory":
                if dev_name in self.Cfg.MEMORY_RANGES:
                    dev = self.Cfg.MEMORY_RANGES[dev_name]
                    reg_def['address'] = dev['address']
                    reg_def['access'] = dev['access']
                else:
                    logger().error("Memory device {} not found".format(dev_name))
        return reg_def

    def get_register_bus(self, reg_name):
        name = self.Cfg.REGISTERS[reg_name].get( 'device', None )
        return self.get_device_bus( name )

    def get_device_bus(self, dev_name):
        return self.Cfg.BUS.get( dev_name, None )

    def read_register(self, reg_name, cpu_thread=0, bus_index=0):
        reg = self.get_register_def( reg_name, bus_index )
        rtype = reg['type']
        reg_value = 0
        if RegisterType.PCICFG == rtype:
            b = int(reg['bus'], 16)
            d = int(reg['dev'], 16)
            f = int(reg['fun'], 16)
            o = int(reg['offset'], 16)
            size = int(reg['size'], 16)
            if   1 == size: reg_value = self.pci.read_byte ( b, d, f, o )
            elif 2 == size: reg_value = self.pci.read_word ( b, d, f, o )
            elif 4 == size: reg_value = self.pci.read_dword( b, d, f, o )
            elif 8 == size: reg_value = (self.pci.read_dword( b, d, f, o+4 ) << 32) | self.pci.read_dword(b, d, f, o)
        elif RegisterType.MMCFG == rtype:
            reg_value = self.mmio.read_mmcfg_reg(int(reg['bus'],16), int(reg['dev'],16), int(reg['fun'],16), int(reg['offset'],16), int(reg['size'],16) )
        elif RegisterType.MMIO == rtype:
            reg_value = self.mmio.read_MMIO_BAR_reg(reg['bar'], int(reg['offset'],16), int(reg['size'],16) )
        elif RegisterType.MSR == rtype:
            (eax, edx) = self.msr.read_msr( cpu_thread, int(reg['msr'],16) )
            reg_value = (edx << 32) | eax
        elif RegisterType.PORTIO == rtype:
            port = int(reg['port'],16)
            size = int(reg['size'],16)
            reg_value = self.io._read_port( port, size )
        elif RegisterType.IOBAR == rtype:
            reg_value = self.iobar.read_IO_BAR_reg( reg['bar'], int(reg['offset'],16), int(reg['size'],16) )
        elif RegisterType.MSGBUS == rtype:
            reg_value = self.msgbus.msgbus_reg_read( int(reg['port'],16), int(reg['offset'],16) )
        elif RegisterType.MM_MSGBUS == rtype:
            reg_value = self.msgbus.mm_msgbus_reg_read(int(reg['port'],16), int(reg['offset'],16))
        elif RegisterType.MEMORY == rtype:
            if reg['access'] == 'dram':
                reg_value= self.mem.read_physical_mem(int(reg['address'],16), int(reg['size'],16))
            elif reg['access'] == 'mmio':
                reg_value = self.mmio.read_MMIO_reg(int(reg['address'],16), int(reg['offset'],16),int(reg['size'],16))
        else:
            raise RegisterTypeNotFoundError("Register type not found: {}".format(rtype))

        return reg_value

    def read_register_all(self, reg_name, cpu_thread=0):
        values = []
        bus_data = self.get_register_bus( reg_name )
        if bus_data is None:
            return [self.read_register( reg_name, cpu_thread )]
        for index in range( len(bus_data) ):
            values.append( self.read_register( reg_name, cpu_thread, index) )
        return values

    def write_register(self, reg_name, reg_value, cpu_thread=0, bus_index=0):
        reg = self.get_register_def( reg_name, bus_index )
        rtype = reg['type']
        if RegisterType.PCICFG == rtype:
            b = int(reg['bus'],16)
            d = int(reg['dev'],16)
            f = int(reg['fun'],16)
            o = int(reg['offset'],16)
            size = int(reg['size'],16)
            if   1 == size: self.pci.write_byte( b, d, f, o, reg_value )
            elif 2 == size: self.pci.write_word( b, d, f, o, reg_value )
            elif 4 == size: self.pci.write_dword( b, d, f, o, reg_value )
            elif 8 == size:
                self.pci.write_dword( b, d, f, o, (reg_value & 0xFFFFFFFF) )
                self.pci.write_dword( b, d, f, o + 4, (reg_value>>32 & 0xFFFFFFFF) )
        elif RegisterType.MMCFG == rtype:
            self.mmio.write_mmcfg_reg(int(reg['bus'],16), int(reg['dev'],16), int(reg['fun'],16), int(reg['offset'],16), int(reg['size'],16), reg_value )
        elif RegisterType.MMIO == rtype:
            self.mmio.write_MMIO_BAR_reg(reg['bar'], int(reg['offset'],16), reg_value, int(reg['size'],16) )
        elif RegisterType.MSR == rtype:
            eax = (reg_value & 0xFFFFFFFF)
            edx = ((reg_value >> 32) & 0xFFFFFFFF)
            self.msr.write_msr( cpu_thread, int(reg['msr'],16), eax, edx )
        elif RegisterType.PORTIO == rtype:
            port = int(reg['port'],16)
            size = int(reg['size'],16)
            self.io._write_port( port, reg_value, size )
        elif RegisterType.IOBAR == rtype:
            self.iobar.write_IO_BAR_reg( reg['bar'], int(reg['offset'],16), int(reg['size'],16), reg_value )
        elif RegisterType.MSGBUS == rtype:
            self.msgbus.msgbus_reg_write( int(reg['port'],16), int(reg['offset'],16), reg_value )
        elif RegisterType.MM_MSGBUS == rtype:
            self.msgbus.mm_msgbus_reg_write(int(reg['port'],16), int(reg['offset'],16), reg_value)
        elif RegisterType.MEMORY == rtype:
            if reg['access'] == 'dram':
                self.mem.write_physical_mem(int(reg['address'],16), int(reg['size'],16), reg_value)
            elif reg['access'] == 'mmio':
                self.mmio.write_MMIO_reg(int(reg['address'],16), int(reg['offset'],16), reg_value, int(reg['size'],16))
        else:
            raise RegisterTypeNotFoundError("Register type not found: {}".format(rtype))

    def write_register_all(self, reg_name, reg_values, cpu_thread=0):
        bus_data = self.get_register_bus( reg_name )
        if bus_data is None:
            return False
        values = len(bus_data)
        if len(reg_values) == values:
            for index in range( values ):
                self.write_register( reg_name, reg_values[index], cpu_thread, index )
            return True
        else:
            return False

    def write_register_all_single(self, reg_name, reg_value, cpu_thread=0):
        bus_data = self.get_register_bus( reg_name )
        if bus_data is None:
            return False
        values = len(bus_data)
        for index in range( values ):
            self.write_register( reg_name, reg_value, cpu_thread, index )
        return True

    def read_register_dict( self, reg_name):
        reg_value = self.read_register(reg_name)
        reg_def = self.get_register_def(reg_name)
        result = reg_def
        result['value'] = reg_value
        for f in reg_def['FIELDS']:
            result['FIELDS'][f]['bit'] = field_bit = int(reg_def['FIELDS'][f]['bit'])
            result['FIELDS'][f]['size'] = field_size = int(reg_def['FIELDS'][f]['size'])
            field_mask = 0
            for i in range(field_size):
                field_mask = (field_mask << 1) | 1
            result['FIELDS'][f]['value'] = (reg_value >> field_bit) & field_mask
        return result

    def get_register_field_mask(self, reg_name, reg_field=None,
                                preserve_field_position=False):
        reg_def = self.get_register_def(reg_name)
        if reg_field is not None:
            field_attrs = reg_def['FIELDS'][reg_field]
            mask_start = int(field_attrs['bit'])
            mask = (1 << int(field_attrs['size'])) - 1
        else:
            mask_start = 0
            mask = (1 << (int(reg_def['size'],16) * 8)) - 1
        if preserve_field_position:
            return mask << mask_start
        else:
            return mask

    def get_register_field(self, reg_name, reg_value, field_name,
                           preserve_field_position=False):
        field_attrs = self.get_register_def(reg_name)['FIELDS'][field_name]
        field_bit   = int(field_attrs['bit'])
        field_mask  = (1 << int(field_attrs['size'])) - 1
        if preserve_field_position: return reg_value & (field_mask << field_bit)
        else:                       return (reg_value >> field_bit) & field_mask

    def get_register_field_all(self, reg_name, reg_values, field_name, preserve_field_position=False):
        values = []
        for reg_value in reg_values:
            values.append( self.get_register_field( reg_name, reg_value, field_name, preserve_field_position) )
        return values

    def set_register_field(self, reg_name, reg_value, field_name,
                           field_value, preserve_field_position=False):
        field_attrs = self.get_register_def(reg_name)['FIELDS'][field_name]
        field_bit   = int(field_attrs['bit'])
        field_mask  = (1 << int(field_attrs['size'])) - 1
        reg_value  &= ~(field_mask << field_bit) # keep other fields
        if preserve_field_position: reg_value |= (field_value & (field_mask << field_bit))
        else:                       reg_value |= ((field_value & field_mask) << field_bit)
        return reg_value

    def set_register_field_all(self, reg_name, reg_values, field_name, field_value, preserve_field_position=False):
        values = []
        for reg_value in reg_values:
            values.append( self.set_register_field( reg_name, reg_value, field_name, field_value, preserve_field_position) )
        return values

    def read_register_field( self, reg_name, field_name, preserve_field_position=False, cpu_thread=0 ):
        reg_value = self.read_register(reg_name, cpu_thread)
        return self.get_register_field(reg_name, reg_value, field_name, preserve_field_position)

    def read_register_field_all(self, reg_name, field_name, preserve_field_position=False, cpu_thread=0):
        reg_values = self.read_register_all(reg_name, cpu_thread)
        return self.get_register_field_all(reg_name, reg_values, field_name, preserve_field_position)

    def write_register_field( self, reg_name, field_name, field_value, preserve_field_position=False, cpu_thread=0 ):
        reg_value = self.read_register(reg_name, cpu_thread)
        reg_value_new = self.set_register_field(reg_name, reg_value, field_name, field_value, preserve_field_position)
        #logger().log("set register {} (0x{:x}) field {} = 0x{:x} ==> 0x{:x}".format(reg_name, reg_value, field_name, field_value, reg_value_new))
        return self.write_register(reg_name, reg_value_new, cpu_thread)

    def write_register_field_all(self, reg_name, field_name, field_value, preserve_field_position=False, cpu_thread=0):
        reg_values = self.read_register_all(reg_name, cpu_thread)
        reg_values_new = self.set_register_field_all(reg_name, reg_values, field_name, field_value, preserve_field_position)
        return self.write_register_all(reg_name, reg_values_new, cpu_thread)

    def register_has_field( self, reg_name, field_name ):
        try:
            reg_def = self.get_register_def(reg_name )
        except KeyError:
            return False
        if 'FIELDS' not in reg_def:
            return False
        return (field_name in reg_def['FIELDS'])

    def _register_fields_str(self, reg_def, reg_val):
        reg_fields_str = ''
        if 'FIELDS' in reg_def:
          reg_fields_str += '\n'
          # sort fields by their bit position in the register
          sorted_fields = sorted( reg_def['FIELDS'].items(), key=lambda field: int(field[1]['bit']) )
          for f in sorted_fields:
            field_attrs = f[1]
            field_bit = int(field_attrs['bit'])
            field_size = int(field_attrs['size'])
            field_mask = 0
            for i in range(field_size):
                field_mask = (field_mask << 1) | 1
            field_value = (reg_val >> field_bit) & field_mask
            field_desc = (' << ' + field_attrs['desc'] + ' ') if (field_attrs['desc'] != '') else ''
            reg_fields_str += ("    [{:02d}] {:16} = {:X}{}\n".format(field_bit,f[0],field_value,field_desc))

        if '' != reg_fields_str: reg_fields_str = reg_fields_str[:-1]
        return reg_fields_str

    def print_register(self, reg_name, reg_val, bus_index=0):
        reg = self.get_register_def( reg_name, bus_index )
        rtype = reg['type']
        reg_str = ''
        reg_val_str = "0x{:0{width}X}".format(reg_val,width=(int(reg['size'],16)*2))
        if RegisterType.PCICFG == rtype or RegisterType.MMCFG == rtype:
            b = int(reg['bus'],16)
            d = int(reg['dev'],16)
            f = int(reg['fun'],16)
            o = int(reg['offset'],16)
            mmcfg_off_str =  ''
            if RegisterType.MMCFG == rtype:
                mmcfg_off_str += ", MMCFG + 0x{:X}".format((b*32*8 + d*8 + f) * 0x1000 + o)
            reg_str = "[*] {} = {} << {} (b:d.f {:02d}:{:02d}.{:d} + 0x{:X}{})".format(reg_name, reg_val_str, reg['desc'], b, d, f, o, mmcfg_off_str)
        elif RegisterType.MMIO == rtype:
            reg_str = "[*] {} = {} << {} ({} + 0x{:X})".format(reg_name, reg_val_str, reg['desc'], reg['bar'], int(reg['offset'],16))
        elif RegisterType.MSR == rtype:
            reg_str = "[*] {} = {} << {} (MSR 0x{:X})".format(reg_name, reg_val_str, reg['desc'], int(reg['msr'],16))
        elif RegisterType.PORTIO == rtype:
            reg_str = "[*] {} = {} << {} (I/O port 0x{:X})".format(reg_name, reg_val_str, reg['desc'], int(reg['port'],16))
        elif RegisterType.IOBAR == rtype:
            reg_str = "[*] {} = {} << {} (I/O {} + 0x{:X})".format(reg_name, reg_val_str, reg['desc'], reg['bar'], int(reg['offset'],16))
        elif RegisterType.MSGBUS == rtype or RegisterType.MM_MSGBUS == rtype:
            reg_str = "[*] {} = {} << {} (msgbus port 0x{:X}, off 0x{:X})".format(reg_name, reg_val_str, reg['desc'], int(reg['port'],16), int(reg['offset'],16))
        else:
            reg_str = "[*] {} = {} << {}".format(reg_name, reg_val_str, reg['desc'])

        reg_str += self._register_fields_str(reg, reg_val)
        logger().log( reg_str )
        return reg_str

    def print_register_all(self, reg_name, cpu_thread=0):
        reg_str = ''
        bus_data = self.get_register_bus( reg_name )
        if bus_data is None:
            return reg_str
        for index in range( len(bus_data) ):
            reg_val = self.read_register( reg_name, cpu_thread, index )
            reg_str += self.print_register( reg_name, reg_val, index )
        return reg_str

    def get_control(self, control_name, cpu_thread=0, with_print=0):
        control = self.Cfg.CONTROLS[ control_name ]
        reg     = control['register']
        field   = control['field']
        reg_data = self.read_register(reg, cpu_thread)
        if with_print: self.print_register(reg, reg_data)
        return self.get_register_field(reg, reg_data, field)

    def set_control(self, control_name, control_value, cpu_thread=0):
        control = self.Cfg.CONTROLS[control_name]
        reg     = control['register']
        field   = control['field']
        return self.write_register_field(reg, field, control_value, cpu_thread)

    def is_control_defined(self, control_name):
        try:
            return (self.Cfg.CONTROLS[ control_name ] is not None)
        except KeyError:
            return False

    def is_all_value(self, reg_values, value):
        return all(n == value for n in reg_values)

    def get_IO_space(self, io_name):
        if io_name in self.Cfg.IO_BARS.keys():
            reg = self.Cfg.IO_BARS[io_name]["register"]
            bf = self.Cfg.IO_BARS[io_name]["base_field"]
            return (reg,bf)
        else:
            return None, None
Example #12
0
class Chipset:
    def __init__(self, helper=None):
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid = 0
        self.did = 0
        self.code = CHIPSET_CODE_UNKNOWN
        self.longname = "Unrecognized Platform"
        self.id = CHIPSET_ID_UNKNOWN
        self.Cfg = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci = Pci(self.helper)
        self.mem = Memory(self.helper)
        self.msr = Msr(self.helper)
        self.ucode = Ucode(self.helper)
        self.io = PortIO(self.helper)
        self.cpuid = CpuID(self.helper)
        #
        # All HAL components which use above 'basic primitive' HAL components
        # should be instantiated in modules/utilcmd with an instance of chipset
        # Example of initializing second order HAL component (UEFI in uefi_cmd.py):
        # cs = cs()
        # self.uefi = UEFI( cs )
        #

    def init(self, platform_code, start_svc):

        if start_svc: self.helper.start()

        if not platform_code:
            vid_did = self.pci.read_dword(0, 0, 0, 0)
            self.vid = vid_did & 0xFFFF
            self.did = (vid_did >> 16) & 0xFFFF
            if VID_INTEL != self.vid:
                raise UnknownChipsetError, (
                    'UnsupportedPlatform: Vendor ID = 0x%04X' % self.vid)
        else:
            if Chipset_Code.has_key(platform_code):
                self.code = platform_code.lower()
            else:
                raise UnknownChipsetError, ('UnsupportedPlatform: code: %s' %
                                            platform_code)
            self.vid = VID_INTEL
            self.did = Chipset_Code[platform_code]

        if Chipset_Dictionary.has_key(self.did):
            data_dict = Chipset_Dictionary[self.did]
            self.code = data_dict['code'].lower()
            self.longname = data_dict['longname']
            self.id = data_dict['id']
        else:
            raise UnknownChipsetError, (
                'UnsupportedPlatform: Device ID = 0x%04X' % self.did)
        self.init_cfg()

    def init_cfg(self):
        if self.code and '' != self.code:
            try:
                exec 'from chipsec.cfg.' + self.code + ' import *'
                logger().log_good(
                    "imported platform specific configuration: chipsec.cfg.%s"
                    % self.code)
                exec 'self.Cfg = ' + self.code + '()'
            except ImportError, msg:
                if logger().VERBOSE:
                    logger().log("[*] Couldn't import chipsec.cfg.%s\n%s" %
                                 (self.code, str(msg)))
Example #13
0
class Chipset:
    def __init__(self, helper=None):
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid = 0
        self.did = 0
        self.code = CHIPSET_CODE_UNKNOWN
        self.longname = "Unrecognized Platform"
        self.id = CHIPSET_ID_UNKNOWN
        self.Cfg = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci = Pci(self.helper)
        self.mem = Memory(self.helper)
        self.msr = Msr(self.helper)
        self.ucode = Ucode(self.helper)
        self.io = PortIO(self.helper)
        self.cpuid = CpuID(self.helper)
        #
        # All HAL components which use above 'basic primitive' HAL components
        # should be instantiated in modules/utilcmd with an instance of chipset
        # Example of initializing second order HAL component (UEFI in uefi_cmd.py):
        # cs = cs()
        # self.uefi = UEFI( cs )
        #

    def init(self, platform_code, start_svc):

        if start_svc:
            self.helper.start()

        if not platform_code:
            vid_did = self.pci.read_dword(0, 0, 0, 0)
            self.vid = vid_did & 0xFFFF
            self.did = (vid_did >> 16) & 0xFFFF
            if VID_INTEL != self.vid:
                raise UnknownChipsetError, ("UnsupportedPlatform: Vendor ID = 0x%04X" % self.vid)
        else:
            if Chipset_Code.has_key(platform_code):
                self.code = platform_code.lower()
            else:
                raise UnknownChipsetError, ("UnsupportedPlatform: code: %s" % platform_code)
            self.vid = VID_INTEL
            self.did = Chipset_Code[platform_code]

        if Chipset_Dictionary.has_key(self.did):
            data_dict = Chipset_Dictionary[self.did]
            self.code = data_dict["code"].lower()
            self.longname = data_dict["longname"]
            self.id = data_dict["id"]
        else:
            raise UnknownChipsetError, ("UnsupportedPlatform: Device ID = 0x%04X" % self.did)
        self.init_cfg()

    def init_cfg(self):
        if self.code and "" != self.code:
            try:
                exec "from chipsec.cfg." + self.code + " import *"
                logger().log_good("imported platform specific configuration: chipsec.cfg.%s" % self.code)
                exec "self.Cfg = " + self.code + "()"
            except ImportError, msg:
                if logger().VERBOSE:
                    logger().log("[*] Couldn't import chipsec.cfg.%s\n%s" % (self.code, str(msg)))
Example #14
0
class Chipset:

    def __init__(self, helper=None):
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid        = 0
        self.did        = 0
        self.code       = ""
        self.longname   = "Unrecognized Platform"
        self.id         = CHIPSET_ID_UNKNOWN

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci    	= Pci      ( self.helper )
        self.mem    	= Memory   ( self.helper )
        self.msr    	= Msr      ( self.helper )
        self.ucode  	= Ucode    ( self.helper )
        self.io     	= PortIO   ( self.helper )
        self.cpuid      = CpuID    ( self.helper )
        #
        # All HAL components which use above 'basic primitive' HAL components
        # should be instantiated in modules/utilcmd with an instance of chipset
        # Example of initializing second order HAL component (UEFI in uefi_cmd.py):
        # cs = cs()
        # self.uefi = UEFI( cs )
        #

    def init( self, platform_code, start_svc ):

        if start_svc: self.helper.start()

        if not platform_code:
            vid_did  = self.pci.read_dword( 0, 0, 0, 0 )
            self.vid = vid_did & 0xFFFF
            self.did = (vid_did >> 16) & 0xFFFF
            if VID_INTEL != self.vid: raise UnknownChipsetError, ('UnsupportedPlatform: Vendor ID = 0x%04X' % self.vid)
        else:
            if Chipset_Code.has_key( platform_code ): self.code = platform_code.lower()
            else: raise UnknownChipsetError, ('UnsupportedPlatform: code: %s' % platform_code)
            self.vid      = VID_INTEL
            self.did      = Chipset_Code[ platform_code ]

        if Chipset_Dictionary.has_key( self.did ):
            data_dict       = Chipset_Dictionary[ self.did ]
            self.code       = data_dict['code'].lower()
            self.longname   = data_dict['longname']
            self.id         = data_dict['id']
        else:
            raise UnknownChipsetError, ('UnsupportedPlatform: Device ID = 0x%04X' % self.did)



    def destroy( self, start_svc ):
        self.stop( start_svc )
        #self.helper.destroy()

    def stop( self, start_svc ):
        if start_svc:
            self.helper.stop()

    def get_chipset_id(self):
        return self.id

    def get_chipset_code(self):
        return self.code

    def get_chipset_name(self, id ):
        return self.longname


    def print_chipset(self):
        logger().log( "Platform: %s\n          VID: %04X\n          DID: %04X" % (self.longname, self.vid, self.did))
Example #15
0
class Chipset:
    def __init__(self, helper=None):
        if logger().VERBOSE:
            logger().log("[Chipset] __init__")
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid = 0
        self.did = 0
        self.code = CHIPSET_CODE_UNKNOWN
        self.longname = "Unrecognized Platform"
        self.id = CHIPSET_ID_UNKNOWN
        self.Cfg = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci = Pci(self)
        self.mem = Memory(self)
        self.msr = Msr(self)
        self.ucode = Ucode(self)
        self.io = PortIO(self)
        self.cpu = chipsec.hal.cpu.CPU(self)
        # self.cr         = CrRegs   ( self )
        self.cpuid = CpuID(self)
        #
        # All HAL components which use above 'basic primitive' HAL components
        # should be instantiated in modules/utilcmd with an instance of chipset
        # Examples:
        # - initializing SPI HAL component in a module:
        #   self.spi = SPI( self.cs )
        # - initializing second order UEFI HAL component in utilcmd extension:
        #   spi = SPI( chipsec_util._cs )
        #

    def init(self, platform_code, start_svc):

        _unknown_platform = False
        if start_svc:
            self.helper.start()

        if platform_code is None:
            vid_did = self.pci.read_dword(0, 0, 0, 0)
            self.vid = vid_did & 0xFFFF
            self.did = (vid_did >> 16) & 0xFFFF
            if VID_INTEL != self.vid:
                _unknown_platform = True
        else:
            self.vid = VID_INTEL
            self.code = platform_code.lower()
            if Chipset_Code.has_key(platform_code):
                self.did = Chipset_Code[platform_code]
            else:
                _unknown_platform = True
                self.did = 0xFFFF

        if Chipset_Dictionary.has_key(self.did):
            data_dict = Chipset_Dictionary[self.did]
            self.code = data_dict["code"].lower()
            self.longname = data_dict["longname"]
            self.id = data_dict["id"]
        else:
            _unknown_platform = True
            self.longname = "UnknownPlatform"

        self.init_cfg()
        if _unknown_platform:
            msg = "Unsupported Platform: VID = 0x%04X, DID = 0x%04X" % (self.vid, self.did)
            logger().error(msg)
            raise UnknownChipsetError, msg

    def destroy(self, start_svc):
        self.stop(start_svc)
        # self.helper.destroy()

    def stop(self, start_svc):
        if start_svc:
            self.helper.stop()

    def get_chipset_id(self):
        return self.id

    def get_chipset_code(self):
        return self.code

    def get_chipset_name(self, id):
        return self.longname

    def print_chipset(self):
        logger().log("[*] Platform: %s\n          VID: %04X\n          DID: %04X" % (self.longname, self.vid, self.did))

    def is_core(self):
        return self.get_chipset_id() in CHIPSET_FAMILY_CORE

    def is_server(self):
        return self.get_chipset_id() in CHIPSET_FAMILY_XEON

    def is_atom(self):
        return self.get_chipset_id() in CHIPSET_FAMILY_ATOM

    ##################################################################################
    #
    # Loading platform configuration from XML files in chipsec/cfg/
    #
    ##################################################################################

    def init_xml_configuration(self):
        _cfg_path = os.path.join(chipsec.file.get_main_dir(), "chipsec/cfg")
        # Load chipsec/cfg/common.xml configuration XML file common for all platforms if it exists
        self.init_cfg_xml(os.path.join(_cfg_path, "common.xml"), self.code)
        # Load chipsec/cfg/<code>.xml configuration XML file if it exists for platform <code>
        if self.code and "" != self.code:
            self.init_cfg_xml(os.path.join(_cfg_path, ("%s.xml" % self.code)), self.code)
        # Load configuration from all other XML files recursively (if any)
        for dirname, subdirs, xml_fnames in os.walk(_cfg_path):
            for _xml in xml_fnames:
                if (
                    fnmatch.fnmatch(_xml, "*.xml")
                    and not fnmatch.fnmatch(_xml, "common.xml")
                    and not (_xml in ["%s.xml" % c.lower() for c in Chipset_Code])
                ):
                    self.init_cfg_xml(os.path.join(dirname, _xml), self.code)
        self.Cfg.XML_CONFIG_LOADED = True

    def init_cfg_xml(self, fxml, code):
        import xml.etree.ElementTree as ET

        if not os.path.exists(fxml):
            return
        if logger().VERBOSE:
            logger().log("[*] looking for platform config in '%s'.." % fxml)
        tree = ET.parse(fxml)
        root = tree.getroot()
        for _cfg in root.iter("configuration"):
            if "platform" not in _cfg.attrib:
                if logger().HAL:
                    logger().log("[*] loading common platform config from '%s'.." % fxml)
            elif code == _cfg.attrib["platform"].lower():
                if logger().HAL:
                    logger().log("[*] loading '%s' platform config from '%s'.." % (code, fxml))
            else:
                continue

            if logger().VERBOSE:
                logger().log("[*] loading integrated devices/controllers..")
            for _pci in _cfg.iter("pci"):
                for _device in _pci.iter("device"):
                    _name = _device.attrib["name"]
                    del _device.attrib["name"]
                    self.Cfg.CONFIG_PCI[_name] = _device.attrib
                    if logger().VERBOSE:
                        logger().log("    + %-16s: %s" % (_name, _device.attrib))
            if logger().VERBOSE:
                logger().log("[*] loading MMIO BARs..")
            for _mmio in _cfg.iter("mmio"):
                for _bar in _mmio.iter("bar"):
                    _name = _bar.attrib["name"]
                    del _bar.attrib["name"]
                    self.Cfg.MMIO_BARS[_name] = _bar.attrib
                    if logger().VERBOSE:
                        logger().log("    + %-16s: %s" % (_name, _bar.attrib))
            if logger().VERBOSE:
                logger().log("[*] loading I/O BARs..")
            for _io in _cfg.iter("io"):
                for _bar in _io.iter("bar"):
                    _name = _bar.attrib["name"]
                    del _bar.attrib["name"]
                    self.Cfg.IO_BARS[_name] = _bar.attrib
                    if logger().VERBOSE:
                        logger().log("    + %-16s: %s" % (_name, _bar.attrib))
            if logger().VERBOSE:
                logger().log("[*] loading memory ranges..")
            for _memory in _cfg.iter("memory"):
                for _range in _memory.iter("range"):
                    _name = _range.attrib["name"]
                    del _range.attrib["name"]
                    self.Cfg.MEMORY_RANGES[_name] = _range.attrib
                    if logger().VERBOSE:
                        logger().log("    + %-16s: %s" % (_name, _range.attrib))
            if logger().VERBOSE:
                logger().log("[*] loading configuration registers..")
            for _registers in _cfg.iter("registers"):
                for _register in _registers.iter("register"):
                    _name = _register.attrib["name"]
                    del _register.attrib["name"]
                    if "size" not in _register.attrib:
                        _register.attrib["size"] = "0x4"
                    if "desc" not in _register.attrib:
                        _register.attrib["desc"] = ""
                    reg_fields = {}
                    if _register.find("field") is not None:
                        for _field in _register.iter("field"):
                            _field_name = _field.attrib["name"]
                            del _field.attrib["name"]
                            if "desc" not in _field.attrib:
                                _field.attrib["desc"] = ""
                            reg_fields[_field_name] = _field.attrib
                        _register.attrib["FIELDS"] = reg_fields
                    self.Cfg.REGISTERS[_name] = _register.attrib
                    if logger().VERBOSE:
                        logger().log("    + %-16s: %s" % (_name, _register.attrib))
            if logger().VERBOSE:
                logger().log("[*] loading controls..")
            for _controls in _cfg.iter("controls"):
                for _control in _controls.iter("control"):
                    _name = _control.attrib["name"]
                    del _control.attrib["name"]
                    self.Cfg.CONTROLS[_name] = _control.attrib
                    if logger().VERBOSE:
                        logger().log("    + %-16s: %s" % (_name, _control.attrib))

    #
    # Load chipsec/cfg/<code>.py configuration file for platform <code>
    #
    def init_cfg(self):
        if self.code and "" != self.code:
            try:
                module_path = "chipsec.cfg." + self.code
                module = importlib.import_module(module_path)
                logger().log_good("imported platform specific configuration: chipsec.cfg.%s" % self.code)
                self.Cfg = getattr(module, self.code)()
            except ImportError, msg:
                if logger().VERBOSE:
                    logger().log("[*] Couldn't import chipsec.cfg.%s\n%s" % (self.code, str(msg)))

        #
        # Initialize platform configuration from XML files
        #
        try:
            self.init_xml_configuration()
        except:
            if logger().VERBOSE:
                logger().log_bad(traceback.format_exc())
            pass
Example #16
0
class Chipset:

    def __init__(self, helper=None):
        if helper is None:
            self.helper = OsHelper()
        else:
            self.helper = helper

        self.vid        = 0xFFFF
        self.did        = 0xFFFF
        self.code       = CHIPSET_CODE_UNKNOWN
        self.longname   = "Unrecognized Platform"
        self.id         = CHIPSET_ID_UNKNOWN
        self.Cfg        = Cfg()

        #
        # Initializing 'basic primitive' HAL components
        # (HAL components directly using native OS helper functionality)
        #
        self.pci        = pci.Pci(self)
        self.mem        = physmem.Memory(self)
        self.msr        = msr.Msr(self)
        self.ucode      = ucode.Ucode(self)
        self.io         = io.PortIO(self)
        self.cpu        = cpu.CPU(self)
        self.msgbus     = msgbus.MsgBus(self)
        self.mmio       = mmio.MMIO(self)
        self.iobar      = iobar.IOBAR(self)
        self.igd        = igd.IGD(self)
        #
        # All HAL components which use above 'basic primitive' HAL components
        # should be instantiated in modules/utilcmd with an instance of chipset
        # Examples:
        # - initializing SPI HAL component in a module or util extension:
        #   self.spi = SPI( self.cs )
        #

    ##################################################################################
    #
    # Iitialization
    #
    ##################################################################################
    def detect_platform( self ):
        vid = 0xFFFF
        did = 0xFFFF
        try:
            vid_did = self.pci.read_dword(0, 0, 0, 0)
            vid = vid_did & 0xFFFF
            did = (vid_did >> 16) & 0xFFFF
        except:
            if logger().DEBUG: logger().error("pci.read_dword couldn't read platform VID/DID")
        return (vid, did)

    def init( self, platform_code, start_driver, driver_exists=False ):

        _unknown_platform = False
        self.helper.start(start_driver, driver_exists)
        logger().log( '[CHIPSEC] API mode: %s' % ('using OS native API (not using CHIPSEC kernel module)' if self.use_native_api() else 'using CHIPSEC kernel module API') )

        if platform_code is None:
            self.vid, self.did = self.detect_platform()
            if VID_INTEL != self.vid:
                _unknown_platform = True
        else:
            self.vid = VID_INTEL
            self.code = platform_code.lower()
            if Chipset_Code.has_key( platform_code ):
                self.did = Chipset_Code[ platform_code ]
            else:
                _unknown_platform = True
                self.did = 0xFFFF

        if Chipset_Dictionary.has_key( self.did ):
            data_dict       = Chipset_Dictionary[ self.did ]
            self.code       = data_dict['code'].lower()
            self.longname   = data_dict['longname']
            self.id         = data_dict['id']

        else:
            _unknown_platform = True
            self.longname   = 'UnknownPlatform'

        self.init_cfg()
        if _unknown_platform and start_driver:
            msg = 'Unsupported Platform: VID = 0x%04X, DID = 0x%04X' % (self.vid,self.did)
            logger().error( msg )
            raise UnknownChipsetError, msg


    def destroy( self, start_driver ):
        self.helper.stop( start_driver )

    def get_chipset_id(self):
        return self.id

    def get_chipset_code(self):
        return self.code

    def get_chipset_name(self, id ):
        return self.longname

    def print_chipset(self):
        logger().log( "[*] Platform: %s\n          VID: %04X\n          DID: %04X" % (self.longname, self.vid, self.did))

    def is_core(self):
        return  self.get_chipset_id() in CHIPSET_FAMILY_CORE

    def is_server(self):
        return  self.get_chipset_id() in CHIPSET_FAMILY_XEON

    def is_atom(self):
        return self.get_chipset_id() in CHIPSET_FAMILY_ATOM

    def use_native_api(self):
        return self.helper.use_native_api()

    ##################################################################################
    #
    # Loading platform configuration from XML files in chipsec/cfg/
    #
    ##################################################################################

    def init_xml_configuration( self ):
        # Create a sorted config file list (xml only)
        _cfg_files = []
        _cfg_path = os.path.join( chipsec.file.get_main_dir(), 'chipsec/cfg' )
        for root, subdirs, files in os.walk(_cfg_path):
            _cfg_files.extend([os.path.join(root, x) for x in files if fnmatch.fnmatch(x, '*.xml')])
        _cfg_files.sort()
        if logger().VERBOSE:
            logger().log("[*] Configuration Files:")
            for _xml in _cfg_files:
                logger().log("[*] - {}".format(_xml))

        # Locate common (chipsec/cfg/common*.xml) configuration XML files.
        loaded_files = []
        for _xml in _cfg_files:
            if fnmatch.fnmatch(os.path.basename(_xml), 'common*.xml'):
                loaded_files.append(_xml)

        # Locate platform specific (chipsec/cfg/<code>*.xml) configuration XML files.
        if self.code and '' != self.code:
            for _xml in _cfg_files:
                if fnmatch.fnmatch(os.path.basename(_xml), '{}*.xml'.format(self.code)):
                    loaded_files.append(_xml)

        # Locate configuration files from all other XML files recursively (if any) excluding other platform configuration files.
        platform_files = []
        for plat in [c.lower() for c in Chipset_Code]:
            platform_files.extend([x for x in _cfg_files if fnmatch.fnmatch(os.path.basename(x), '{}*.xml'.format(plat))])
        loaded_files.extend([x for x in _cfg_files if x not in loaded_files and x not in platform_files])

        # Load all configuration files for this platform.
        if logger().VERBOSE: logger().log("[*] Loading Configuration Files:")
        for _xml in loaded_files:
            self.init_cfg_xml(_xml, self.code)
        self.Cfg.XML_CONFIG_LOADED = True


    def init_cfg_xml(self, fxml, code):
        import xml.etree.ElementTree as ET
        if not os.path.exists( fxml ): return
        if logger().VERBOSE: logger().log( "[*] looking for platform config in '%s'.." % fxml )
        tree = ET.parse( fxml )
        root = tree.getroot()
        for _cfg in root.iter('configuration'):
            if 'platform' not in _cfg.attrib:
                if logger().HAL: logger().log( "[*] loading common platform config from '%s'.." % fxml )
            elif code == _cfg.attrib['platform'].lower():
                if logger().HAL: logger().log( "[*] loading '%s' platform config from '%s'.." % (code,fxml) )
            else: continue

            if logger().VERBOSE: logger().log( "[*] loading integrated devices/controllers.." )
            for _pci in _cfg.iter('pci'):
                for _device in _pci.iter('device'):
                    _name = _device.attrib['name']
                    del _device.attrib['name']
                    if 'undef' in _device.attrib and _name in self.Cfg.CONFIG_PCI:
                        if logger().VERBOSE: logger().log("    - {:16}: {}".format(_name, _device.attrib['undef']))
                        self.Cfg.CONFIG_PCI.pop(_name, None)
                        continue
                    self.Cfg.CONFIG_PCI[ _name ] = _device.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _device.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading MMIO BARs.." )
            for _mmio in _cfg.iter('mmio'):
                for _bar in _mmio.iter('bar'):
                    _name = _bar.attrib['name']
                    del _bar.attrib['name']
                    if 'undef' in _bar.attrib and _name in self.Cfg.MMIO_BARS:
                        if logger().VERBOSE: logger().log("    - {:16}: {}".format(_name, _bar.attrib['undef']))
                        self.Cfg.MMIO_BARS.pop(_name, None)
                        continue
                    self.Cfg.MMIO_BARS[ _name ] = _bar.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _bar.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading I/O BARs.." )
            for _io in _cfg.iter('io'):
                for _bar in _io.iter('bar'):
                    _name = _bar.attrib['name']
                    del _bar.attrib['name']
                    if 'undef' in _bar.attrib and _name in self.Cfg.IO_BARS:
                        if logger().VERBOSE: logger().log("    - {:16}: {}".format(_name, _bar.attrib['undef']))
                        self.Cfg.IO_BARS.pop(_name, None)
                        continue
                    self.Cfg.IO_BARS[ _name ] = _bar.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _bar.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading memory ranges.." )
            for _memory in _cfg.iter('memory'):
                for _range in _memory.iter('range'):
                    _name = _range.attrib['name']
                    del _range.attrib['name']
                    if 'undef' in _range.attrib and _name in self.Cfg.MEMORY_RANGES:
                        if logger().VERBOSE: logger().log("    - {:16}: {}".format(_name, _range.attrib['undef']))
                        self.Cfg.MEMORY_RANGES.pop(_name, None)
                        continue
                    self.Cfg.MEMORY_RANGES[ _name ] = _range.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _range.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading configuration registers.." )
            for _registers in _cfg.iter('registers'):
                for _register in _registers.iter('register'):
                    _name = _register.attrib['name']
                    del _register.attrib['name']
                    if 'undef' in _register.attrib and _name in self.Cfg.REGISTERS:
                        if logger().VERBOSE: logger().log("    - {:16}: {}".format(_name, _register.attrib['undef']))
                        self.Cfg.REGISTERS.pop(_name, None)
                        continue
                    if 'size' not in _register.attrib: _register.attrib['size'] = "0x4"
                    if 'desc' not in _register.attrib: _register.attrib['desc'] = ''
                    reg_fields = {}
                    if _register.find('field') is not None:
                        for _field in _register.iter('field'):
                            _field_name = _field.attrib['name']
                            del _field.attrib['name']
                            if 'desc' not in _field.attrib: _field.attrib['desc'] = ''
                            reg_fields[ _field_name ] = _field.attrib
                        _register.attrib['FIELDS'] = reg_fields
                    self.Cfg.REGISTERS[ _name ] = _register.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _register.attrib) )
            if logger().VERBOSE: logger().log( "[*] loading controls.." )
            for _controls in _cfg.iter('controls'):
                for _control in _controls.iter('control'):
                    _name = _control.attrib['name']
                    del _control.attrib['name']
                    if 'undef' in _control.attrib and _name in self.Cfg.CONTROLS:
                        if logger().VERBOSE: logger().log("    - {:16}: {}".format(_name, _control.attrib['undef']))
                        self.Cfg.CONTROLS.pop(_name, None)
                        continue
                    self.Cfg.CONTROLS[ _name ] = _control.attrib
                    if logger().VERBOSE: logger().log( "    + %-16s: %s" % (_name, _control.attrib) )

    #
    # Load chipsec/cfg/<code>.py configuration file for platform <code>
    #
    def init_cfg(self):
        if self.code and '' != self.code:
            try:
                module_path = 'chipsec.cfg.' + self.code
                module = importlib.import_module( module_path )
                logger().log_good( "imported platform specific configuration: chipsec.cfg.%s" % self.code )
                self.Cfg = getattr( module, self.code )()
            except ImportError, msg:
                if logger().VERBOSE: logger().log( "[*] Couldn't import chipsec.cfg.%s\n%s" % ( self.code, str(msg) ) )

        #
        # Initialize platform configuration from XML files
        #
        try:
            self.init_xml_configuration()
        except:
            if logger().VERBOSE: logger().log_bad(traceback.format_exc())
            pass