mirror of
https://github.com/chipsec/chipsec
synced 2026-06-08 13:31:00 +00:00
f7409804b4
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
175 lines
8.3 KiB
Python
175 lines
8.3 KiB
Python
# CHIPSEC: Platform Security Assessment Framework
|
|
# Copyright (c) 2010-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 mmio list
|
|
>>> chipsec_util mmio dump <MMIO_BAR_name> [offset] [length]
|
|
>>> chipsec_util mmio dump-abs <MMIO_base_address> [offset] [length]
|
|
>>> chipsec_util mmio read <MMIO_BAR_name> <offset> <width>
|
|
>>> chipsec_util mmio read-abs <MMIO_base_address> <offset> <width>
|
|
>>> chipsec_util mmio write <MMIO_BAR_name> <offset> <width> <value>
|
|
>>> chipsec_util mmio write-abs <MMIO_base_address> <offset> <width> <value>
|
|
|
|
Examples:
|
|
|
|
>>> chipsec_util mmio list
|
|
>>> chipsec_util mmio dump MCHBAR
|
|
>>> chipsec_util mmio dump-abs 0xFE010000 0x70 0x10
|
|
>>> chipsec_util mmio read SPIBAR 0x74 0x4
|
|
>>> chipsec_util mmio read-abs 0xFE010000 0x74 0x04
|
|
>>> chipsec_util mmio write SPIBAR 0x74 0x4 0xFFFF0000
|
|
>>> chipsec_util mmio write-abs 0xFE010000 0x74 0x04 0xFFFF0000
|
|
"""
|
|
|
|
from chipsec.command import BaseCommand, toLoad
|
|
from chipsec.hal.common import mmio
|
|
from argparse import ArgumentParser
|
|
|
|
|
|
# ###################################################################
|
|
#
|
|
# Access to Memory Mapped PCIe Configuration Space (MMCFG)
|
|
#
|
|
# ###################################################################
|
|
class MMIOCommand(BaseCommand):
|
|
|
|
def requirements(self) -> toLoad:
|
|
return toLoad.All
|
|
|
|
def parse_arguments(self) -> None:
|
|
parser = ArgumentParser(prog='chipsec_util mmio', usage=__doc__)
|
|
subparsers = parser.add_subparsers()
|
|
|
|
parser_list = subparsers.add_parser('list')
|
|
parser_list.set_defaults(func=self.list_bars)
|
|
|
|
parser_dump = subparsers.add_parser('dump')
|
|
parser_dump.add_argument('bar_name', type=str, help='MMIO BAR to dump')
|
|
parser_dump.add_argument('offset', type=lambda x: int(x, 16), nargs='?', default=0,
|
|
help='Offset in BAR to start dump')
|
|
parser_dump.add_argument('length', type=lambda x: int(x, 16), nargs='?', default=None,
|
|
help='Length of the region to dump')
|
|
parser_dump.set_defaults(func=self.dump_bar)
|
|
|
|
parser_dump_abs = subparsers.add_parser('dump-abs')
|
|
parser_dump_abs.add_argument('base', type=lambda x: int(x, 16), help='MMIO region base address')
|
|
parser_dump_abs.add_argument('offset', type=lambda x: int(x, 16), nargs='?', default=0,
|
|
help='Offset in BAR to start dump')
|
|
parser_dump_abs.add_argument('length', type=lambda x: int(x, 16), nargs='?', default=None,
|
|
help='Length of the region to dump')
|
|
parser_dump_abs.set_defaults(func=self.dump_bar_abs)
|
|
|
|
parser_read = subparsers.add_parser('read')
|
|
parser_read.add_argument('bar_name', type=str, help='MMIO BAR to read')
|
|
parser_read.add_argument('offset', type=lambda x: int(x, 16), help='Offset value (hex)')
|
|
parser_read.add_argument('width', type=lambda x: int(x, 16), choices=[1, 2, 4, 8],
|
|
help='Width value [1, 2, 4, 8] (hex)')
|
|
parser_read.add_argument('bus', type=lambda x: int(x, 16), nargs='?', default=None, help='bus value')
|
|
parser_read.set_defaults(func=self.read_bar)
|
|
|
|
parser_read_abs = subparsers.add_parser('read-abs')
|
|
parser_read_abs.add_argument('base', type=lambda x: int(x, 16), help='MMIO region base address')
|
|
parser_read_abs.add_argument('offset', type=lambda x: int(x, 16), help='MMIO register offset')
|
|
parser_read_abs.add_argument('width', type=lambda x: int(x, 16), choices=[1, 2, 4, 8],
|
|
help='Data width to read')
|
|
parser_read_abs.set_defaults(func=self.read_abs)
|
|
|
|
parser_write = subparsers.add_parser('write')
|
|
parser_write.add_argument('bar_name', type=str, help='MMIO BAR to write')
|
|
parser_write.add_argument('offset', type=lambda x: int(x, 16), help='Offset value (hex)')
|
|
parser_write.add_argument('width', type=lambda x: int(x, 16), choices=[1, 2, 4, 8],
|
|
help='Width value [1, 2, 4, 8] (hex)')
|
|
parser_write.add_argument('value', type=lambda x: int(x, 16), help='Value to write (hex)')
|
|
parser_write.add_argument('bus', type=lambda x: int(x, 16), nargs='?', default=None, help='bus value')
|
|
parser_write.set_defaults(func=self.write_bar)
|
|
|
|
parser_write_abs = subparsers.add_parser('write-abs')
|
|
parser_write_abs.add_argument('base', type=lambda x: int(x, 16), help='MMIO region base address')
|
|
parser_write_abs.add_argument('offset', type=lambda x: int(x, 16), help='MMIO register offset')
|
|
parser_write_abs.add_argument('width', type=lambda x: int(x, 16), choices=[1, 2, 4, 8],
|
|
help='Data width to read')
|
|
parser_write_abs.add_argument('value', type=lambda x: int(x, 16), help='Value to write (hex)')
|
|
parser_write_abs.set_defaults(func=self.write_abs)
|
|
|
|
parser.parse_args(self.argv, namespace=self)
|
|
|
|
def set_up(self) -> None:
|
|
self._mmio = mmio.MMIO(self.cs)
|
|
|
|
def list_bars(self):
|
|
self._mmio.list_MMIO_BARs()
|
|
|
|
def dump_bar(self):
|
|
self.logger.log("[CHIPSEC] Dumping {} MMIO space..".format(self.bar_name.upper()))
|
|
(bar_base, bar_size) = self._mmio.get_MMIO_BAR_base_address(self.bar_name.upper())
|
|
if self.length is not None:
|
|
bar_size = self.length
|
|
else:
|
|
bar_size -= self.offset
|
|
bar_base += self.offset
|
|
self._mmio.dump_MMIO(bar_base, bar_size)
|
|
|
|
def dump_bar_abs(self):
|
|
tmp_base = self.base + self.offset
|
|
if self.length is None:
|
|
tmp_length = 0x1000
|
|
else:
|
|
tmp_length = self.length
|
|
self.logger.log("[CHIPSEC] Dumping MMIO space 0x{:08X} to 0x{:08X}".format(tmp_base, tmp_base + tmp_length))
|
|
self._mmio.dump_MMIO(tmp_base, tmp_length)
|
|
|
|
def read_bar(self):
|
|
bar = self.bar_name.upper()
|
|
reg = self._mmio.read_MMIO_BAR_reg(bar, self.offset, self.width, self.bus)
|
|
self.logger.log("[CHIPSEC] Read {} + 0x{:X}: 0x{:08X}".format(bar, self.offset, reg))
|
|
|
|
def read_abs(self):
|
|
if self.width == 1:
|
|
reg = self._mmio.read_MMIO_reg_byte(self.base, self.offset)
|
|
elif self.width == 2:
|
|
reg = self._mmio.read_MMIO_reg_word(self.base, self.offset)
|
|
elif self.width == 4:
|
|
reg = self._mmio.read_MMIO_reg_dword(self.base, self.offset)
|
|
elif self.width == 8:
|
|
reg = self._mmio.read_MMIO_reg_dword(self.base, self.offset)
|
|
reg |= self._mmio.read_MMIO_reg_dword(self.base, self.offset + 4) << 32
|
|
self.logger.log("[CHIPSEC] Read 0x{:X} + 0x{:X}: 0x{:08X}".format(self.base, self.offset, reg))
|
|
|
|
def write_bar(self):
|
|
bar = self.bar_name.upper()
|
|
self.logger.log("[CHIPSEC] Write {} + 0x{:X}: 0x{:08X}".format(bar, self.offset, self.value))
|
|
self._mmio.write_MMIO_BAR_reg(bar, self.offset, self.value, self.width, self.bus)
|
|
|
|
def write_abs(self):
|
|
self.logger.log("[CHIPSEC] Write 0x{:X} + 0x{:X}: 0x{:08X}".format(self.base, self.offset, self.value))
|
|
if self.width == 1:
|
|
self._mmio.write_MMIO_reg_byte(self.base, self.offset, self.value & 0xFF)
|
|
elif self.width == 2:
|
|
self._mmio.write_MMIO_reg_word(self.base, self.offset, self.value & 0xFFFF)
|
|
elif self.width == 4:
|
|
self._mmio.write_MMIO_reg_dword(self.base, self.offset, self.value & 0xFFFFFFFF)
|
|
elif self.width == 8:
|
|
self._mmio.write_MMIO_reg_dword(self.base, self.offset, self.value & 0xFFFFFFFF)
|
|
self._mmio.write_MMIO_reg_dword(self.base, self.offset + 4, (self.value >> 32) & 0xFFFFFFFF)
|
|
|
|
|
|
|
|
commands = {'mmio': MMIOCommand}
|