Files
chipsec-chipsec/chipsec/utilcmd/config_cmd.py
William Leara 79f81bbb7e fix for flake8 rules related to whitespace
This commit fixes whitespace errors from checkers W291,W292,W293,W391.  They were found by running "flake8 ." from the root directory.  These are errors defined by "pycodestyle", and have no functional impact to the source.  This is simply fixing whitespace as defined by CHIPSEC's .flake8 configuration.

background:
https://www.flake8rules.com/rules/W291.html
https://www.flake8rules.com/rules/W292.html
https://www.flake8rules.com/rules/W293.html
https://www.flake8rules.com/rules/W391.html

tool versions: flake8 v7.3.0, python v3.13.11

Signed-off-by: William Leara <william.leara@dell.com>
2026-03-10 14:20:23 -07:00

430 lines
17 KiB
Python

# !/usr/bin/python
# CHIPSEC: Platform Security Assessment Framework
# Copyright (c) 2021, Intel Corporation
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; Version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
# Contact information:
# chipsec@intel.com
"""
>>> chipsec_util config show [config] <name>
Examples:
>>> chipsec_util config show ALL
>>> chipsec_util config show [CONFIG_PCI|MEMORY_RANGES|MM_MSGBUS|MSGBUS|IO|MSR]
>>> chipsec_util config show SCOPE
"""
from argparse import ArgumentParser
from chipsec.command import BaseCommand, toLoad
class CONFIGCommand(BaseCommand):
"""Command to display configuration information."""
# Initialize command
def __init__(self, argv, cs):
"""Initialize the command with base class and set options."""
super(CONFIGCommand, self).__init__(argv, cs)
self.skip_list = ["LOCKS", "CONTROLS", "ALL"]
try:
# Get parent keys from scope manager
self.all_options = (
self.cs.Cfg.scope_manager.parent_keys +
self.skip_list + ["SCOPE"]
)
except (AttributeError, TypeError):
# Fallback if scope_manager is not available
self.all_options = [
"CONFIG_PCI_RAW", "CONFIG_PCI", "MEMORY_RANGES", "MM_MSGBUS",
"MSGBUS", "IO", "MSR", "MMIO_BARS", "IO_BARS", "LOCKS",
"CONTROLS", "ALL", "SCOPE"
]
self.child_details = False # Default to not showing child details
# Command setup and infrastructure methods
def requirements(self):
"""Specify resource requirements for this command."""
return toLoad.All
def parse_arguments(self):
"""Parse command line arguments."""
parser = ArgumentParser(usage='chipsec_util config')
subparsers = parser.add_subparsers()
# Show command
parser_show = subparsers.add_parser('show')
parser_show.add_argument(
'config',
choices=self.all_options,
default="ALL"
)
parser_show.add_argument(
'-c', '--child-details',
action='store_true',
help='Include child details'
)
parser_show.set_defaults(func=self.show, config="ALL")
parser.parse_args(self.argv, namespace=self)
return True
# Main display methods
def show(self):
"""Show configuration information based on selected option."""
if self.config == "SCOPE":
self.scope_details()
return
if self.config == "ALL":
# Exclude SCOPE from all_options when processing ALL
config = [x for x in self.all_options if x != "SCOPE"]
# Also show scope information when 'ALL' is selected
self.scope_details()
else:
config = [self.config]
for mconfig in config:
if mconfig in self.skip_list:
continue
try:
cfg = getattr(self.cs.Cfg, mconfig)
except AttributeError:
self.logger.log(f"\n{mconfig} - Not available")
continue
self.logger.log(f"\n{mconfig}")
for vid in cfg.keys():
self.logger.log(f"{vid}:")
for name in cfg[vid].keys():
if mconfig in ["CONFIG_PCI_RAW"]:
cfg_data = cfg[vid][name]
self.logger.log(
f'\t{name} - {self.pci_details(cfg_data)}'
)
elif mconfig in ["CONFIG_PCI"]:
cfg_data = cfg[vid][name]
self.logger.log(
f'\t{name} - {self.pci_details(cfg_data)}'
)
elif mconfig == "MEMORY_RANGES":
self.logger.log(
f'\t{name} - {self.memory_details(cfg[vid][name])}'
)
elif mconfig in ["MM_MSGBUS", "MSGBUS", "IO"]:
port_details = self.get_port_details(cfg[vid][name])
self.logger.log(f'\t{name} - {port_details}')
elif mconfig in ["MMIO_BARS", "IO_BARS"]:
for cfg_data in cfg[vid][name]:
details = self.mmio_details(
cfg[vid][name][cfg_data]
)
self.logger.log(f'\t{cfg_data} - {details}')
elif mconfig == "MSR":
self.logger.log(
f'\t{name} - {self.msr_details(cfg[vid][name])}'
)
if (self.child_details and
mconfig not in ["CONFIG_PCI_RAW"]):
if mconfig not in ["MMIO_BARS", "IO_BARS"]:
self.get_child_details(vid, name)
else:
for cfg_data in cfg[vid][name]:
self.get_child_details(
vid, cfg[vid][name][cfg_data].name
)
if set(config).intersection({"LOCKS", "ALL"}):
self.lock_details()
if set(config).intersection({"CONTROLS", "ALL"}):
self.control_details()
return
# Detail formatting methods for different types of registers/configurations
def msr_details(self, regi):
"""Format MSR register details."""
ret = f'config: {regi.config}'
return ret
def memory_details(self, regi):
"""Format memory range details."""
try:
# Try to access as dictionary first
if isinstance(regi, dict):
# Basic attributes always displayed
ret = (f"access: {regi.get('access', 'N/A')}, "
f"address: {regi.get('address', 'N/A')}, "
f"size: {regi.get('size', 'N/A')}")
# Add configuration if available
if 'config' in regi:
ret += f", config: {regi['config']}"
# BEGIN: Extended MMIO Functionality
# Display extended MMIO attributes if available
if 'base_ref' in regi:
ret += f", base_ref: {regi['base_ref']}"
if 'base_value' in regi:
ret += f" (0x{regi['base_value']:x})"
if 'ip_ref' in regi:
ret += f", ip_ref: {regi['ip_ref']}"
if 'ip_value' in regi:
ret += f" (0x{regi['ip_value']:x})"
if 'scope' in regi:
ret += f", scope: {regi['scope']}"
# END: Extended MMIO Functionality
else:
# Fall back to attribute access if it's an object
ret = (f"access: {getattr(regi, 'access', 'N/A')}, "
f"address: {getattr(regi, 'address', 'N/A')}, "
f"size: {getattr(regi, 'size', 'N/A')}")
# Add configuration if available
if hasattr(regi, 'config'):
ret += f", config: {regi.config}"
# BEGIN: Extended MMIO Functionality
# Display extended MMIO attributes if available
if hasattr(regi, 'base_ref') and regi.base_ref:
ret += f", base_ref: {regi.base_ref}"
if hasattr(regi, 'base_value') and regi.base_value:
ret += f" (0x{regi.base_value:x})"
if hasattr(regi, 'ip_ref') and regi.ip_ref:
ret += f", ip_ref: {regi.ip_ref}"
if hasattr(regi, 'ip_value') and regi.ip_value:
ret += f" (0x{regi.ip_value:x})"
if hasattr(regi, 'scope') and regi.scope:
ret += f", scope: {regi.scope}"
# END: Extended MMIO Functionality
except (KeyError, AttributeError):
# In case of any error, just return the string representation
ret = str(regi)
return ret
def get_port_details(self, regi):
"""Format port details."""
ret = ''
if regi:
ret = f'port: {regi.port}, config: {regi.config}'
return ret
def ima_details(self, regi):
"""Format IMA register details."""
base_value = regi['base'] if 'base' in regi.keys() else None
ret = f"index: {regi['index']}, data: {regi['data']}, " \
f"base: {base_value}"
return ret
def register_details(self, regi):
"""Format register details based on type."""
ret = ""
if regi['type'] == 'pcicfg' or regi['type'] == 'mmcfg':
ret = f"device: {regi['device']}, offset: {regi['offset']}, " \
f"size: {regi['size']}"
elif regi['type'] == 'mmio':
ret = f"bar: {regi['bar']}, offset: {regi['offset']}, " \
f"size: {regi['size']}"
elif regi['type'] == 'mm_msgbus':
ret = f"offset: {regi['offset']}, size: {regi['size']}"
elif regi['type'] == 'io':
ret = f"size: {regi['size']}"
elif regi['type'] == 'iobar':
ret = f"bar: {regi['bar']}, offset: {regi['offset']}, " \
f"size: {regi['size']}"
elif regi['type'] == 'msr':
if 'size' in regi:
ret = f"msr: {regi['msr']}, size: {regi['size']}"
else:
ret = f"msr: {regi['msr']}"
elif regi['type'] == 'R Byte':
if 'size' in regi:
ret = f"offset: {regi['offset']}, size: {regi['size']}"
else:
ret = f"offset: {regi['offset']}"
elif regi['type'] == 'memory':
ret = f"access: {regi['access']}, offset: {regi['offset']}, " \
f"size: {regi['size']}"
# Add field information if available
try:
if isinstance(regi, (list, tuple)) and len(regi) > 0:
reg_obj = regi[0]
if hasattr(reg_obj, 'fields') and reg_obj.fields:
for key in reg_obj.fields:
bit = reg_obj.fields[key]['bit']
size = reg_obj.fields[key]['size']
end_bit = bit + size - 1
ret += f'\n\t\t\t{key} - bit {bit}:{end_bit}'
except (IndexError, AttributeError, TypeError):
# Silently ignore errors when accessing fields
pass
return ret
def pci_details(self, regi):
"""Format PCI configuration details."""
return str(regi)
def mmio_details(self, regi):
"""Format MMIO details."""
return str(regi)
def io_details(self, regi):
"""Format IO details."""
if 'register' in regi:
fixed_addr = (
regi['fixed_address'] if 'fixed_address' in regi else None
)
ret = (f"register: {regi['register']}, "
f"base_field: {regi['base_field']}, "
f"size: {regi['size']}, "
f"fixed_addr: {fixed_addr}")
else:
size = regi['size'] if 'size' in regi else None
fixed_addr = (
regi['fixed_address'] if 'fixed_address' in regi else None
)
ret = (f"bus: {regi['bus']}, "
f"dev: {regi['dev']}, "
f"func: {regi['fun']}, "
f"reg: {regi['reg']}, "
f"mask: {regi['mask']}, "
f"size: {size}, "
f"fixed_addr: {fixed_addr}")
return ret
# Data display methods for child details, controls, and locks
def get_child_details(self, vid, dev):
"""Get and display child configuration details."""
self.logger.log(f'get_child details {dev}')
config = self.cs.Cfg.child_keys
for mconfig in config:
if mconfig in ["CONTROLS", "LOCKS", "LOCKEDBY"]:
continue
cfg = getattr(self.cs.Cfg, mconfig)
self.logger.log(f"\t{mconfig}:")
if mconfig == "IMA_REGISTERS":
if vid in cfg and dev in cfg[vid]:
for name in cfg[vid][dev].keys():
details = self.ima_details(cfg[vid][dev][name])
self.logger.log(f'\t\t{name} - {details}')
elif mconfig == "REGISTERS":
try:
if vid in cfg and dev in cfg[vid]:
for name in cfg[vid][dev].keys():
details = self.register_details(
cfg[vid][dev][name]
)
self.logger.log(f'\t\t{name} - {details}')
except KeyError:
pass
self.logger.log("")
def control_details(self):
"""Display control details."""
self.logger.log("\nCONTROLS")
try:
cfg = getattr(self.cs.Cfg, "CONTROLS")
for regi in cfg.keys():
self.logger.log(f'\t{regi}')
except AttributeError as e:
self.logger.log(f"\tError retrieving controls: {e}")
return
def lock_details(self):
"""Display lock details."""
self.logger.log("\nLOCKS")
try:
locks = self.cs.Cfg.get_lock_list()
for lock in locks:
lock_cfg = self.cs.Cfg.get_lock_obj(lock)
self.logger.log(f'\t{lock_cfg}')
except AttributeError as e:
self.logger.log(f"\tError retrieving locks: {e}")
return
def scope_details(self):
"""Display the contents of the scope manager."""
self.logger.log("\nSCOPE MANAGER")
# Display parent keys
self.logger.log("\nParent Keys:")
for key in self.cs.Cfg.scope_manager.parent_keys:
self.logger.log(f"\t{key}")
# Display child keys
self.logger.log("\nChild Keys:")
for key in self.cs.Cfg.scope_manager.child_keys:
self.logger.log(f"\t{key}")
# Display current scope
self.logger.log("\nCurrent Scope:")
for scope_key, scope_value in self.cs.Cfg.scope.items():
key_name = scope_key if scope_key is not None else "DEFAULT"
self.logger.log(f"\t{key_name}: {scope_value}")
# BEGIN: Extended MMIO Functionality
# Display memory bases if available
if hasattr(self.cs.Cfg, 'memory_bases') and self.cs.Cfg.memory_bases:
self.logger.log("\nMemory Bases:")
for base_name, base_value in self.cs.Cfg.memory_bases.items():
self.logger.log(f"\t{base_name}: 0x{base_value:x}")
# Display IP addresses if available
if hasattr(self.cs.Cfg, 'ip_addresses') and self.cs.Cfg.ip_addresses:
self.logger.log("\nIP Addresses:")
for ip_name, ip_value in self.cs.Cfg.ip_addresses.items():
self.logger.log(f"\t{ip_name}: 0x{ip_value:x}")
# END: Extended MMIO Functionality
# Display available scopes in the configuration
self.logger.log("\nAvailable Configuration Items:")
# Go through parent keys and display available items
for parent_key in self.cs.Cfg.scope_manager.parent_keys:
if hasattr(self.cs.Cfg, parent_key):
cfg_data = getattr(self.cs.Cfg, parent_key)
if cfg_data:
self.logger.log(f"\n{parent_key}:")
for vid in cfg_data.keys():
self.logger.log(f"\t{vid}:")
if isinstance(cfg_data[vid], dict):
# Limit to first 10 items for readability
items = list(cfg_data[vid].keys())
for name in items[:10]:
self.logger.log(f"\t\t{name}")
if len(items) > 10:
remaining = len(items) - 10
self.logger.log(
f"\t\t... ({remaining} more items)"
)
return
commands = {'config': CONFIGCommand}