diff --git a/chipsec/cfg/parsers/registers/controls.py b/chipsec/cfg/parsers/controls.py similarity index 100% rename from chipsec/cfg/parsers/registers/controls.py rename to chipsec/cfg/parsers/controls.py diff --git a/chipsec/cfg/parsers/core_parsers.py b/chipsec/cfg/parsers/core_parsers.py index 9641f41a63..633d938a7a 100644 --- a/chipsec/cfg/parsers/core_parsers.py +++ b/chipsec/cfg/parsers/core_parsers.py @@ -27,17 +27,17 @@ from chipsec.cfg.parsers.ip.msgbus import MSGBUSConfig from chipsec.cfg.parsers.ip.msr import MSRConfig from chipsec.cfg.parsers.ip.pci_device import PCIConfig -from chipsec.cfg.parsers.registers.controls import CONTROLHelper -from chipsec.cfg.parsers.registers.io import IORegisters -from chipsec.cfg.parsers.registers.iobar import IOBARRegisters -from chipsec.cfg.parsers.registers.memory import MEMORYRegisters -from chipsec.cfg.parsers.registers.mm_msgbus import MM_MSGBUSRegisters -from chipsec.cfg.parsers.registers.mmcfg import MMCFGRegisters -from chipsec.cfg.parsers.registers.mmio import MMIORegisters -from chipsec.cfg.parsers.registers.msgbus import MSGBUSRegisters -from chipsec.cfg.parsers.registers.msr import MSRRegisters -from chipsec.cfg.parsers.registers.pci import PCIRegisters -from chipsec.cfg.parsers.registers.locks import LOCKSHelper +from chipsec.cfg.parsers.controls import CONTROLHelper +from chipsec.cfg.parsers.locks import LOCKSHelper +from chipsec.cfg.parsers.registers.io import IORegisters # +from chipsec.cfg.parsers.registers.iobar import IOBARRegisters # +from chipsec.cfg.parsers.registers.memory import MEMORYRegisters # +from chipsec.cfg.parsers.registers.mm_msgbus import MM_MSGBUSRegisters # +from chipsec.cfg.parsers.registers.mmcfg import MMCFGRegisters # +from chipsec.cfg.parsers.registers.mmio import MMIORegisters # +from chipsec.cfg.parsers.registers.msgbus import MSGBUSRegisters # +from chipsec.cfg.parsers.registers.msr import MSRRegisters # +from chipsec.cfg.parsers.registers.pci import PCIRegisters #pcicfg from chipsec.parsers import BaseConfigParser from chipsec.parsers import Stage from chipsec.parsers import info_data, config_data diff --git a/chipsec/cfg/parsers/registers/locks.py b/chipsec/cfg/parsers/locks.py similarity index 100% rename from chipsec/cfg/parsers/registers/locks.py rename to chipsec/cfg/parsers/locks.py diff --git a/chipsec/config.py b/chipsec/config.py index 30c317f2b6..79e7b103b4 100644 --- a/chipsec/config.py +++ b/chipsec/config.py @@ -528,21 +528,8 @@ def get_mmio_def(self, bar_name): ret = self.MMIO_BARS[vid][device][bar] return ret - def get_io_def(self, bar_name): - scope = self.get_scope(bar_name) - vid, device, bar, _ = self.convert_internal_scope(scope, bar_name) - if bar in self.IO_BARS[vid][device]: - return self.IO_BARS[vid][device][bar] - else: - return None - def get_mem_def(self, range_name): - scope = self.get_scope(range_name) - vid, range, _, _ = self.convert_internal_scope(scope, range_name) - if range in self.MEMORY_RANGES[vid]: - return self.MEMORY_RANGES[vid][range] - else: - return None + def get_device_bus(self, dev_name): scope = self.get_scope(dev_name) diff --git a/chipsec/hal/physmem.py b/chipsec/hal/physmem.py index 7122dde7f1..1c38a84e2c 100644 --- a/chipsec/hal/physmem.py +++ b/chipsec/hal/physmem.py @@ -29,9 +29,10 @@ """ from struct import unpack, pack -from typing import Tuple, Optional +from typing import Any, Dict, Tuple, Optional from chipsec.hal.hal_base import HALBase from chipsec.library.logger import print_buffer_bytes +from chipsec.library.bits import make_mask class Memory(HALBase): @@ -163,10 +164,16 @@ def get_max_memory_bit_size(self): def get_max_memory_mask(self): size = self.get_max_memory_bit_size() - return self.get_bit_mask(size) + return make_mask(size) - def get_bit_mask(self, size): - return (1 << size) - 1 def get_value_from_bit_def(self, inputValue, fieldStartBit, fieldSize): return (inputValue >> fieldStartBit) & self.get_bit_mask(fieldSize) + + def get_def(self, range_name: str) -> Dict[str, Any]: + '''Return address access of a MEM register''' + scope = self.cs.Cfg.get_scope(range_name) + vid, range, _, _ = self.cs.Cfg.convert_internal_scope(scope, range_name) + if vid in self.cs.Cfg.MEMORY_RANGES and range in self.cs.Cfg.MEMORY_RANGES[vid]: + return self.cs.Cfg.MEMORY_RANGES[vid][range] + return None diff --git a/chipsec/library/register.py b/chipsec/library/register.py index 010714000f..b7c425d40a 100644 --- a/chipsec/library/register.py +++ b/chipsec/library/register.py @@ -29,6 +29,15 @@ from chipsec.library.bits import set_bits, get_bits, make_mask from chipsec.library.defines import is_all_ones from chipsec.library.exceptions import CSReadError, RegisterTypeNotFoundError, UninitializedRegisterError +from chipsec.library.registers.io import IO +from chipsec.library.registers.iobar import IOBar +from chipsec.library.registers.memory import Memory +from chipsec.library.registers.mm_msgbus import MMMsgBus +from chipsec.library.registers.mmcfg import MMCfg +from chipsec.library.registers.mmio import MMIO +from chipsec.library.registers.msgbus import MsgBus +from chipsec.library.registers.msr import MSR +from chipsec.library.registers.pcicfg import PCICfg class RegisterType: @@ -47,6 +56,15 @@ class RegisterType: class Register: def __init__(self, cs): self.cs = cs + self.io = IO(cs) + self.iobar = IOBar(cs) + self.memory = Memory(cs) + self.mm_msgbus = MMMsgBus(cs) + self.mmcfg = MMCfg(cs) + self.mmio = MMIO(cs) + self.msgbus = MsgBus(cs) + self.msr = MSR(cs) + self.pcicfg = PCICfg(cs) def is_defined(self, reg_name: str) -> bool: """Checks if register is defined in the XML config""" @@ -57,23 +75,6 @@ def is_defined(self, reg_name: str) -> bool: except KeyError: return False - # def is_device_enabled(self, reg_name: str, bus: Optional[int]=None) -> bool: - # """Checks if device is defined in the XML config""" - # if reg_name in self.cs.Cfg.REGISTERS: - # reg = self.get_def(reg_name) - # rtype = reg['type'] - # if (rtype == RegisterType.MMCFG) or (rtype == RegisterType.PCICFG): - # if bus is not None: - # b = bus - # else: - # b = self.cs.device.get_first_bus(reg) - # d = reg['dev'] - # f = reg['fun'] - # return self.cs.pci.is_enabled(b, d, f) - # elif (rtype == RegisterType.MMIO): - # bar_name = reg['bar'] - # return self.cs.mmio.is_MMIO_BAR_enabled(bar_name, bus) - # return False def _get_pci_def(self, reg_def: Dict[str, Any], vid: str, dev_name: str) -> Dict[str, Any]: """Return Bus Dev Fun of a PCI register""" @@ -83,13 +84,6 @@ def _get_pci_def(self, reg_def: Dict[str, Any], vid: str, dev_name: str) -> Dict reg_def['fun'] = dev.fun return reg_def - def _get_memory_def(self, reg_def: Dict[str, Any], vid: str, dev_name: str) -> Dict[str, Any]: - """Return address access of a MEM register""" - dev = self.cs.Cfg.MEMORY_RANGES[vid][dev_name] - reg_def['address'] = dev['address'] - reg_def['access'] = dev['access'] - return reg_def - def _get_mmmsgbus_def(self, reg_def: Dict[str, Any], vid: str, dev_name: str) -> Dict[str, Any]: """Return port address of a MM_MSGBUS register""" dev = self.cs.Cfg.MM_MSGBUS[vid][dev_name] @@ -120,7 +114,7 @@ def get_def(self, reg_name: str) -> Dict[str, Any]: reg_def = self.cs.Cfg.REGISTERS[vid][dev_name][register] def_type_map = {RegisterType.PCICFG: self._get_pci_def, RegisterType.MMCFG: self._get_pci_def, - RegisterType.MEMORY: self._get_memory_def, + # RegisterType.MEMORY: self._get_memory_def, RegisterType.MM_MSGBUS: self._get_mmmsgbus_def, RegisterType.IMA: self._get_indirect_def} # breakpoint() @@ -141,386 +135,6 @@ def get_obj(self, reg_name: str, instance=None): return RegList() - # def get_bus(self, reg_name: str) -> List[int]: - # """Returns list of buses device/register was discovered on""" - # device = self.cs.Cfg.REGISTERS[reg_name].get('device', '') - # if not device: - # if logger().DEBUG: - # logger().log_important(f"No device found for '{reg_name}'") - # if 'bus' in self.cs.Cfg.REGISTERS[reg_name]: - # return [self.cs.Cfg.REGISTERS[reg_name]['bus']] - # else: - # return [] - # return self.cs.device.get_bus(device) - - # def _read_pci(self, bus: Optional[int], reg: Dict[str, Any], rtype: str, do_check: bool) -> int: - # """Returns PCI register value""" - # reg_value = 0 - # if bus is not None: - # b = self.cs.device.get_first(bus) - # else: - # b = self.cs.device.get_first_bus(reg) - # d = reg['dev'] - # f = reg['fun'] - # o = reg['offset'] - # size = reg['size'] - # if do_check and self.cs.consistency_checking: - # if self.cs.pci.get_DIDVID(b, d, f) == (0xFFFF, 0xFFFF): - # raise CSReadError(f'PCI Device is not available ({b}:{d}.{f})') - # if RegisterType.PCICFG == rtype: - # if 1 == size: - # reg_value = self.cs.pci.read_byte(b, d, f, o) - # elif 2 == size: - # reg_value = self.cs.pci.read_word(b, d, f, o) - # elif 4 == size: - # reg_value = self.cs.pci.read_dword(b, d, f, o) - # elif 8 == size: - # reg_value = (self.cs.pci.read_dword(b, d, f, o + 4) << 32) | self.cs.pci.read_dword(b, d, f, o) - # elif RegisterType.MMCFG == rtype: - # reg_value = self.cs.mmio.read_mmcfg_reg(b, d, f, o, size) - # return reg_value - - # def _read_mmio(self, bus: Optional[int], reg: Dict[str, Any]) -> int: - # """Returns MMIO register value""" - # _bus = bus - # if self.cs.mmio.get_MMIO_BAR_base_address(reg['bar'], _bus)[0] != 0: - # reg_value = self.cs.mmio.read_MMIO_BAR_reg(reg['bar'], reg['offset'], reg['size'], _bus) - # else: - # raise CSReadError(f'MMIO Bar ({reg["bar"]}) base address is 0') - # return reg_value - - # def _read_msr(self, cpu_thread: int, reg: Dict[str, Any]) -> int: - # """Returns MSR register value""" - # (eax, edx) = self.cs.msr.read_msr(cpu_thread, reg['msr']) - # return (edx << 32) | eax - - # def _read_portio(self, reg: Dict[str, Any]) -> int: - # """Returns PORTIO register value""" - # port = reg['port'] - # size = reg['size'] - # return self.cs.io._read_port(port, size) - - # def _read_iobar(self, reg: Dict[str, Any]) -> int: - # """Returns IOBAR register value""" - # if self.cs.iobar.get_IO_BAR_base_address(reg['bar'])[0] != 0: - # reg_value = self.cs.iobar.read_IO_BAR_reg(reg['bar'], reg['offset'], reg['size']) - # else: - # raise CSReadError(f'IO Bar ({reg["bar"]}) base address is 0') - # return reg_value - - # def _read_memory(self, reg: Dict[str, Any]) -> int: - # """Returns MEM register value""" - # reg_value = 0 - # if reg['access'] == 'dram': - # size = reg['size'] - # if 1 == size: - # reg_value = self.cs.mem.read_physical_mem_byte(reg['address']) - # elif 2 == size: - # reg_value = self.cs.mem.read_physical_mem_word(reg['address']) - # elif 4 == size: - # reg_value = self.cs.mem.read_physical_mem_dword(reg['address']) - # elif 8 == size: - # reg_value = self.cs.mem.read_physical_mem_qword(reg['address']) - # elif reg['access'] == 'mmio': - # reg_value = self.cs.mmio.read_MMIO_reg(reg['address'], reg['offset'], reg['size']) - # return reg_value - - # def _read_ima(self, reg: Dict[str, Any]) -> int: - # """Returns IMA register value""" - # self.write(reg['index'], reg['offset'] + reg['base']) - # return self.read(reg['data']) - - # def read(self, reg_name: str, cpu_thread: int=0, bus: Optional[int]=None, do_check: bool=True) -> int: - # """Reads configuration register (by name)""" - - # reg = self.get_def(reg_name) - # rtype = reg['type'] - # reg_value = 0 - # if (rtype == RegisterType.PCICFG) or (rtype == RegisterType.MMCFG): - # reg_value = self._read_pci(bus, reg, rtype, do_check) - # elif rtype == RegisterType.MMIO: - # reg_value = self._read_mmio(bus, reg) - # elif rtype == RegisterType.MSR: - # reg_value = self._read_msr(cpu_thread, reg) - # elif rtype == RegisterType.PORTIO: - # reg_value = self._read_portio(reg) - # elif rtype == RegisterType.IOBAR: - # reg_value = self._read_iobar(reg) - # elif rtype == RegisterType.MSGBUS: - # reg_value = self.cs.msgbus.msgbus_reg_read(reg['port'], reg['offset']) - # elif rtype == RegisterType.MM_MSGBUS: - # reg_value = self.cs.msgbus.mm_msgbus_reg_read(reg['port'], reg['offset']) - # elif rtype == RegisterType.MEMORY: - # reg_value = self._read_memory(reg) - # elif rtype == RegisterType.IMA: - # reg_value = self._read_ima(reg) - # else: - # raise RegisterTypeNotFoundError(f'Register type not found: {rtype}') - - # return reg_value - - # def read_all(self, reg_name: str, cpu_thread: int=0) -> List[int]: - # """Reads all configuration register instances (by name)""" - # values = [] - # bus_data = self.get_bus(reg_name) - # reg = self.get_def(reg_name) - # rtype = reg['type'] - # if RegisterType.MSR == rtype: - # topology = self.cs.cpu.get_cpu_topology() - # if 'scope' in reg.keys() and reg['scope'] == "packages": - # packages = topology['packages'] - # threads_to_use = [packages[p][0] for p in packages] - # elif 'scope' in reg.keys() and reg['scope'] == "cores": - # cores = topology['cores'] - # threads_to_use = [cores[p][0] for p in cores] - # else: # Default to threads - # threads_to_use = range(self.cs.helper.get_threads_count()) - # for t in threads_to_use: - # values.append(self.read(reg_name, t)) - # elif rtype in [RegisterType.MMCFG, RegisterType.PCICFG, RegisterType.MMIO]: - # if bus_data: - # for bus in bus_data: - # values.append(self.read(reg_name, cpu_thread, bus)) - # else: - # values.append(self.read(reg_name, cpu_thread)) - # return values - - # def _write_pci(self, bus: Optional[int], reg: Dict[str, Any], rtype: str, reg_value: int) -> None: - # """Writes PCI register value""" - # if bus is not None: - # b = bus - # else: - # b = self.cs.device.get_first_bus(reg) - # d = reg['dev'] - # f = reg['fun'] - # o = reg['offset'] - # size = reg['size'] - # if RegisterType.PCICFG == rtype: - # if 1 == size: - # self.cs.pci.write_byte(b, d, f, o, reg_value) - # elif 2 == size: - # self.cs.pci.write_word(b, d, f, o, reg_value) - # elif 4 == size: - # self.cs.pci.write_dword(b, d, f, o, reg_value) - # elif 8 == size: - # self.cs.pci.write_dword(b, d, f, o, (reg_value & 0xFFFFFFFF)) - # self.cs.pci.write_dword(b, d, f, o + 4, (reg_value >> 32 & 0xFFFFFFFF)) - # elif RegisterType.MMCFG == rtype: - # self.cs.mmio.write_mmcfg_reg(b, d, f, o, size, reg_value) - - # def _write_msr(self, reg: Dict[str, Any], reg_value: int, cpu_thread: int) -> None: - # """Writes MSR register value""" - # eax = (reg_value & 0xFFFFFFFF) - # edx = ((reg_value >> 32) & 0xFFFFFFFF) - # self.cs.msr.write_msr(cpu_thread, reg['msr'], eax, edx) - - # def _write_portio(self, reg: Dict[str, Any], reg_value: int) -> None: - # """Writes PORTIO register value""" - # port = reg['port'] - # size = reg['size'] - # self.cs.io._write_port(port, reg_value, size) - - # def _write_memory(self, reg: Dict[str, Any], reg_value: int) -> None: - # """Writes MEM register value""" - # if reg['access'] == 'dram': - # self.cs.mem.write_physical_mem(reg['address'], reg['size'], reg_value) - # elif reg['access'] == 'mmio': - # self.cs.mmio.write_MMIO_reg(reg['address'], reg['offset'], reg_value, reg['size']) - - # def _write_ima(self, reg: Dict[str, Any], reg_value: int) -> None: - # """Writes IMA register value""" - # self.write(reg['index'], reg['offset'] + reg['base']) - # self.write(reg['data'], reg_value) - - # def write(self, reg_name: str, reg_value: int, cpu_thread: int=0, bus: Optional[int]=None) -> bool: - # """Writes configuration register (by name)""" - # reg = self.get_def(reg_name) - # rtype = reg['type'] - # if (rtype == RegisterType.PCICFG) or (rtype == RegisterType.MMCFG): - # self._write_pci(bus, reg, rtype, reg_value) - # elif rtype == RegisterType.MMIO: - # self.cs.mmio.write_MMIO_BAR_reg(reg['bar'], reg['offset'], reg_value, reg['size'], bus) - # elif rtype == RegisterType.MSR: - # self._write_msr(reg, reg_value, cpu_thread) - # elif rtype == RegisterType.PORTIO: - # self._write_portio(reg, reg_value) - # elif rtype == RegisterType.IOBAR: - # self.cs.iobar.write_IO_BAR_reg(reg['bar'], reg['offset'], reg['size'], reg_value) - # elif rtype == RegisterType.MSGBUS: - # self.cs.msgbus.msgbus_reg_write(reg['port'], reg['offset'], reg_value) - # elif rtype == RegisterType.MM_MSGBUS: - # self.cs.msgbus.mm_msgbus_reg_write(reg['port'], reg['offset'], reg_value) - # elif rtype == RegisterType.MEMORY: - # self._write_memory(reg, reg_value) - # elif rtype == RegisterType.IMA: - # self._write_ima(reg, reg_value) - # else: - # raise RegisterTypeNotFoundError(f'Register type not found: {rtype}') - # return True - - # def _write_msr_all(self, reg: Dict[str, Any], reg_name: str, reg_values: List[int]) -> bool: - # """Writes values to all instances of an MSR register""" - # ret = False - # topology = self.cs.cpu.get_cpu_topology() - # if 'scope' in reg.keys() and reg['scope'] == "packages": - # packages = topology['packages'] - # threads_to_use = [packages[p][0] for p in packages] - # elif 'scope' in reg.keys() and reg['scope'] == "cores": - # cores = topology['cores'] - # threads_to_use = [cores[p][0] for p in cores] - # else: # Default to threads - # threads_to_use = range(self.cs.helper.get_threads_count()) - # if len(reg_values) == len(threads_to_use): - # value = 0 - # for t in threads_to_use: - # self.write(reg_name, reg_values[value], t) - # value += 1 - # ret = True - # return ret - - # def _write_pci_all(self, reg_name: str, reg_values: List[int], cpu_thread: int, bus_data: List[int]) -> bool: - # """Writes values to all instances of a PCI register""" - # ret = False - # values = len(bus_data) - # if len(reg_values) == values: - # for index in range(values): - # self.write(reg_name, reg_values[index], cpu_thread, bus_data[index]) - # ret = True - # return ret - - # def write_all(self, reg_name: str, reg_values: List[int], cpu_thread: int=0) -> bool: - # """Writes all configuration register instances (by name)""" - # reg = self.get_def(reg_name) - # rtype = reg['type'] - # bus_data = self.get_bus(reg_name) - # ret = False - # if rtype == RegisterType.MSR: - # ret = self._write_msr_all(reg, reg_name, reg_values) - # elif rtype in [RegisterType.MMCFG, RegisterType.PCICFG, RegisterType.MMIO] and bus_data: - # ret = self._write_pci_all(reg_name, reg_values, cpu_thread, bus_data) - # else: - # if len(reg_values) == 1: - # ret = self.write(reg_name, reg_values[0]) - # if not ret and logger().DEBUG: - # logger().log("[write_register_all] There is a mismatch in the number of register values and registers to write") - # return ret - - # def write_all_single(self, reg_name: str, reg_value: int, cpu_thread: int=0) -> bool: - # """Writes all configuration register instances (by name)""" - # reg = self.get_def(reg_name) - # rtype = reg['type'] - # bus_data = self.get_bus(reg_name) - # if RegisterType.MSR == rtype: - # topology = self.cs.cpu.get_cpu_topology() - # if 'scope' in reg.keys() and reg['scope'] == "packages": - # packages = topology['packages'] - # threads_to_use = [packages[p][0] for p in packages] - # elif 'scope' in reg.keys() and reg['scope'] == "cores": - # cores = topology['cores'] - # threads_to_use = [cores[p][0] for p in cores] - # else: # Default to threads - # threads_to_use = range(self.cs.helper.get_threads_count()) - # for t in threads_to_use: - # self.write(reg_name, reg_value, t) - # elif rtype in [RegisterType.MMCFG, RegisterType.PCICFG, RegisterType.MMIO] and bus_data: - # for bus in bus_data: - # self.write(reg_name, reg_value, cpu_thread, bus) - # else: - # self.write(reg_name, reg_value) - # return True - - # def read_dict(self, reg_name: str) -> Dict[str, Any]: - # """Returns complete register definition (with values)""" - # reg_value = self.read(reg_name) - # reg_def = self.get_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): #TODO: update this routine - # field_mask = (field_mask << 1) | 1 - # result['FIELDS'][f]['value'] = (reg_value >> field_bit) & field_mask - # return result - - # def get_field_mask(self, reg_name: str, reg_field: Optional[str]=None, preserve_field_position: bool=False) -> int: - # """Returns the field mask for a register field definition (by name)""" - # reg_def = self.get_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 << (reg_def['size'] * 8)) - 1 - # if preserve_field_position: - # return mask << mask_start - # else: - # return mask - - # def get_field(self, reg_name: str, reg_value: int, field_name: str, preserve_field_position: bool=False) -> int: - # """Reads the value of the field (by name) of configuration register (by register value)""" - # field_attrs = self.get_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_field_all(self, reg_name: str, reg_values: List[int], field_name: str, preserve_field_position: bool=False) -> List[int]: - # """Reads the value of the field (by name) of all configuration register instances (by register value)""" - # values = [] - # for reg_value in reg_values: - # values.append(self.get_field(reg_name, reg_value, field_name, preserve_field_position)) - # return values - - # def set_field(self, reg_name: str, reg_value: int, field_name: str, field_value: int, preserve_field_position: bool=False) -> int: - # """writes the value of the field (by name) of configuration register (by register value)""" - # field_attrs = self.get_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_field_all(self, reg_name: str, reg_values: List[int], field_name: str, field_value: int, preserve_field_position: bool=False) -> List[int]: - # """Writes the value of the field (by name) of all configuration register instances (by register value)""" - # values = [] - # for reg_value in reg_values: - # values.append(self.set_field(reg_name, reg_value, field_name, field_value, preserve_field_position)) - # return values - - # def read_field(self, reg_name: str, field_name: str, preserve_field_position: bool=False, cpu_thread: int=0, bus: Optional[int]=None) -> int: - # """Reads the value of the field (by name) of configuration register (by register name)""" - # reg_value = self.read(reg_name, cpu_thread, bus) - # return self.get_field(reg_name, reg_value, field_name, preserve_field_position) - - # def read_field_all(self, reg_name: str, field_name: str, preserve_field_position: bool=False, cpu_thread: int=0) -> List[int]: - # """Reads the value of the field (by name) of all configuration register instances (by register name)""" - # reg_values = self.read_all(reg_name, cpu_thread) - # return self.get_field_all(reg_name, reg_values, field_name, preserve_field_position) - - # def write_field(self, reg_name: str, field_name: str, field_value: int, preserve_field_position: bool=False, cpu_thread: int=0) -> bool: - # """Writes the value of the field (by name) of configuration register (by register name)""" - # try: - # reg_value = self.read(reg_name, cpu_thread) - # reg_value_new = self.set_field(reg_name, reg_value, field_name, field_value, preserve_field_position) - # ret = self.write(reg_name, reg_value_new, cpu_thread) - # except Exception: - # ret = False - # return ret - - # def write_field_all(self, reg_name: str, field_name: str, field_value: int, preserve_field_position: bool=False, cpu_thread: int=0) -> bool: - # """Writes the value of the field (by name) of all configuration register instances (by register name)""" - # reg_values = self.read_all(reg_name, cpu_thread) - # reg_values_new = self.set_field_all(reg_name, reg_values, field_name, field_value, preserve_field_position) - # return self.write_all(reg_name, reg_values_new, cpu_thread) - def has_field(self, reg_name: str, field_name: str) -> bool: scope = self.cs.Cfg.get_scope(reg_name) vid, device, register, _ = self.cs.Cfg.convert_internal_scope(scope, reg_name) @@ -540,94 +154,6 @@ def has_field(self, reg_name: str, field_name: str) -> bool: # break # return ret - # def _fields_str(self, reg_def: Dict[str, Any], reg_val: int) -> str: - # """Returns string of all fields of a register and their values.""" - # 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 = f' << {field_attrs["desc"]} ' if (field_attrs['desc'] != '') else '' - # reg_fields_str += f' [{field_bit:02d}] {f[0]:16} = {field_value:X}{field_desc}\n' - - # if reg_fields_str: - # reg_fields_str = reg_fields_str[:-1] - # return reg_fields_str - - # def print(self, reg_name: str, reg_val: int, bus: Optional[int]=None, cpu_thread: int=0) -> str: - # """Prints configuration register""" - # reg = self.get_def(reg_name) - # rtype = reg['type'] - # reg_str = '' - # reg_width = reg["size"] * 2 - # reg_val_str = f'0x{reg_val:0{reg_width:d}X}' - # if RegisterType.PCICFG == rtype or RegisterType.MMCFG == rtype: - # if bus is not None: - # b = bus - # else: - # b = self.cs.device.get_first_bus(reg) - # d = reg['dev'] - # f = reg['fun'] - # o = reg['offset'] - # mmcfg_off_str = '' - # if RegisterType.MMCFG == rtype: - # mmcfg_off = (b * 32 * 8 + d * 8 + f) * 0x1000 + o - # mmcfg_off_str += f', MMCFG + 0x{mmcfg_off:X}' - # reg_str = f'[*] {reg_name} = {reg_val_str} << {reg["desc"]} (b:d.f {b:02d}:{d:02d}.{f:d} + 0x{o:X}{mmcfg_off_str})' - # elif RegisterType.MMIO == rtype: - # reg_str = f'[*] {reg_name} = {reg_val_str} << {reg["desc"]} ({reg["bar"]} + 0x{reg["offset"]:X})' - # elif RegisterType.MSR == rtype: - # reg_str = f'[*] {reg_name} = {reg_val_str} << {reg["desc"]} (MSR 0x{reg["msr"]:X} Thread 0x{cpu_thread:X})' - # elif RegisterType.PORTIO == rtype: - # reg_str = f'[*] {reg_name} = {reg_val_str} << {reg["desc"]} (I/O port 0x{reg["port"]:X})' - # elif RegisterType.IOBAR == rtype: - # reg_str = f'[*] {reg_name} = {reg_val_str} << {reg["desc"]} (I/O {reg["bar"]} + 0x{reg["offset"]:X})' - # elif RegisterType.MSGBUS == rtype or RegisterType.MM_MSGBUS == rtype: - # reg_str = f'[*] {reg_name} = {reg_val_str} << {reg["desc"]} (msgbus port 0x{reg["port"]:X}, off 0x{reg["offset"]:X})' - # elif RegisterType.IMA == rtype: - # reg_str = f'[*] {reg_name} = {reg_val_str} << {reg["desc"]} (indirect access via {reg["index"]}/{reg["data"]}, base 0x{reg["base"]:X}, off 0x{reg["offset"]:X})' - # else: - # reg_str = f'[*] {reg_name} = {reg_val_str} << {reg["desc"]}' - - # reg_str += self._fields_str(reg, reg_val) - # logger().log(reg_str) - # return reg_str - - # def print_all(self, reg_name: str, cpu_thread: int=0) -> str: - # """Prints all configuration register instances""" - # reg_str = '' - # bus_data = self.get_bus(reg_name) - # reg = self.get_def(reg_name) - # rtype = reg['type'] - # if RegisterType.MSR == rtype: - # topology = self.cs.cpu.get_cpu_topology() - # if 'scope' in reg.keys() and reg['scope'] == "packages": - # packages = topology['packages'] - # threads_to_use = [packages[p][0] for p in packages] - # elif 'scope' in reg.keys() and reg['scope'] == "cores": - # cores = topology['cores'] - # threads_to_use = [cores[p][0] for p in cores] - # else: # Default to threads - # threads_to_use = range(self.cs.helper.get_threads_count()) - # for t in threads_to_use: - # reg_val = self.read(reg_name, t) - # reg_str += self.print(reg_name, reg_val, cpu_thread=t) - # elif rtype in [RegisterType.MMCFG, RegisterType.PCICFG, RegisterType.MMIO] and bus_data: - # for bus in bus_data: - # reg_val = self.read(reg_name, cpu_thread, bus) - # reg_str += self.print(reg_name, reg_val, bus) - # else: - # reg_val = self.read(reg_name, cpu_thread) - # reg_str = self.print(reg_name, reg_val) - # return reg_str # def is_msr(self, reg_name: str) -> bool: # """Returns True if register is type `msr`""" diff --git a/chipsec/library/registers/baseregister.py b/chipsec/library/registers/baseregister.py new file mode 100644 index 0000000000..963dcbec64 --- /dev/null +++ b/chipsec/library/registers/baseregister.py @@ -0,0 +1,34 @@ +# CHIPSEC: Platform Security Assessment Framework +# Copyright (c) 2024, 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 +# + +''' +Abstract register parent +''' + +from chipsec.library.exceptions import UnimplementedAPIError + +class BaseRegister(): + def __init__(self, cs) -> None: + # super(BaseRegister, self).__init__(cs) + self.cs = cs + + def get_def(): + raise UnimplementedAPIError() + \ No newline at end of file diff --git a/chipsec/library/registers/io.py b/chipsec/library/registers/io.py new file mode 100644 index 0000000000..bd306178b2 --- /dev/null +++ b/chipsec/library/registers/io.py @@ -0,0 +1,37 @@ +# CHIPSEC: Platform Security Assessment Framework +# Copyright (c) 2024, 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 +# + +''' +Main functionality to get the definition of IO registers +''' + +from chipsec.library.registers.baseregister import BaseRegister + +class IO(BaseRegister): + def __init__(self, cs): + super(IO, self).__init__(cs) + + def get_def(self, bar_name): + scope = self.cs.Cfg.get_scope(bar_name) + vid, device, bar, _ = self.cs.Cfg.convert_internal_scope(scope, bar_name) + if bar in self.cs.Cfg.IO_BARS[vid][device]: + return self.cs.Cfg.IO_BARS[vid][device][bar] + else: + return None \ No newline at end of file diff --git a/chipsec/library/registers/iobar.py b/chipsec/library/registers/iobar.py new file mode 100644 index 0000000000..49a2d1c81a --- /dev/null +++ b/chipsec/library/registers/iobar.py @@ -0,0 +1,38 @@ +# CHIPSEC: Platform Security Assessment Framework +# Copyright (c) 2024, 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 +# + +''' +Main functionality to get the definition of IO registers +''' + +from chipsec.library.registers.baseregister import BaseRegister + +class IOBar(BaseRegister): + def __init__(self, cs): + super(IOBar, self).__init__(cs) + + def get_def(self, bar_name): + pass + # scope = self.cs.Cfg.get_scope(bar_name) + # vid, device, bar, _ = self.cs.Cfg.convert_internal_scope(scope, bar_name) + # if bar in self.cs.Cfg.IO_BARS[vid][device]: + # return self.cs.Cfg.IO_BARS[vid][device][bar] + # else: + # return None \ No newline at end of file diff --git a/chipsec/library/registers/memory.py b/chipsec/library/registers/memory.py new file mode 100644 index 0000000000..f7d755f856 --- /dev/null +++ b/chipsec/library/registers/memory.py @@ -0,0 +1,37 @@ +# CHIPSEC: Platform Security Assessment Framework +# Copyright (c) 2024, 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 +# + +''' +Main functionality to get the definition of IO registers +''' + +from chipsec.library.registers.baseregister import BaseRegister + +class Memory(BaseRegister): + def __init__(self, cs): + super(Memory, self).__init__(cs) + + def get_def(self, range_name): + scope = self.cs.Cfg.get_scope(range_name) + vid, range, _, _ = self.cs.Cfg.convert_internal_scope(scope, range_name) + if range in self.cs.Cfg.MEMORY_RANGES[vid]: + return self.cs.Cfg.MEMORY_RANGES[vid][range] + else: + return None \ No newline at end of file diff --git a/chipsec/library/registers/mm_msgbus.py b/chipsec/library/registers/mm_msgbus.py new file mode 100644 index 0000000000..acd64b515a --- /dev/null +++ b/chipsec/library/registers/mm_msgbus.py @@ -0,0 +1,37 @@ +# CHIPSEC: Platform Security Assessment Framework +# Copyright (c) 2024, 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 +# + +''' +Main functionality to get the definition of IO registers +''' + +from chipsec.library.registers.baseregister import BaseRegister + +class MMMsgBus(BaseRegister): + def __init__(self, cs): + super(MMMsgBus, self).__init__(cs) + + def get_def(self, bar_name): + scope = self.cs.Cfg.get_scope(bar_name) + vid, device, bar, _ = self.cs.Cfg.convert_internal_scope(scope, bar_name) + if bar in self.cs.Cfg.IO_BARS[vid][device]: + return self.cs.Cfg.IO_BARS[vid][device][bar] + else: + return None \ No newline at end of file diff --git a/chipsec/library/registers/mmcfg.py b/chipsec/library/registers/mmcfg.py new file mode 100644 index 0000000000..506e5e0b82 --- /dev/null +++ b/chipsec/library/registers/mmcfg.py @@ -0,0 +1,37 @@ +# CHIPSEC: Platform Security Assessment Framework +# Copyright (c) 2024, 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 +# + +''' +Main functionality to get the definition of IO registers +''' + +from chipsec.library.registers.baseregister import BaseRegister + +class MMCfg(BaseRegister): + def __init__(self, cs): + super(MMCfg, self).__init__(cs) + + def get_def(self, bar_name): + scope = self.cs.Cfg.get_scope(bar_name) + vid, device, bar, _ = self.cs.Cfg.convert_internal_scope(scope, bar_name) + if bar in self.cs.Cfg.IO_BARS[vid][device]: + return self.cs.Cfg.IO_BARS[vid][device][bar] + else: + return None \ No newline at end of file diff --git a/chipsec/library/registers/mmio.py b/chipsec/library/registers/mmio.py new file mode 100644 index 0000000000..55aebe61b1 --- /dev/null +++ b/chipsec/library/registers/mmio.py @@ -0,0 +1,38 @@ +# CHIPSEC: Platform Security Assessment Framework +# Copyright (c) 2024, 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 +# + +''' +Main functionality to get the definition of IO registers +''' + +from chipsec.library.registers.baseregister import BaseRegister + +class MMIO(BaseRegister): + def __init__(self, cs): + super(MMIO, self).__init__(cs) + + def get_def(self, bar_name): + ret = None + scope = self.cs.Cfg.get_scope(bar_name) + vid, device, bar, _ = self.cs.Cfg.convert_internal_scope(scope, bar_name) + if vid in self.cs.Cfg.MMIO_BARS and device in self.cs.Cfg.MMIO_BARS[vid]: + if bar in self.cs.Cfg.MMIO_BARS[vid][device]: + ret = self.cs.Cfg.MMIO_BARS[vid][device][bar] + return ret \ No newline at end of file diff --git a/chipsec/library/registers/msgbus.py b/chipsec/library/registers/msgbus.py new file mode 100644 index 0000000000..d507afad6c --- /dev/null +++ b/chipsec/library/registers/msgbus.py @@ -0,0 +1,37 @@ +# CHIPSEC: Platform Security Assessment Framework +# Copyright (c) 2024, 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 +# + +''' +Main functionality to get the definition of IO registers +''' + +from chipsec.library.registers.baseregister import BaseRegister + +class MsgBus(BaseRegister): + def __init__(self, cs): + super(MsgBus, self).__init__(cs) + + def get_def(self, bar_name): + scope = self.cs.Cfg.get_scope(bar_name) + vid, device, bar, _ = self.cs.Cfg.convert_internal_scope(scope, bar_name) + if bar in self.cs.Cfg.IO_BARS[vid][device]: + return self.cs.Cfg.IO_BARS[vid][device][bar] + else: + return None \ No newline at end of file diff --git a/chipsec/library/registers/msr.py b/chipsec/library/registers/msr.py new file mode 100644 index 0000000000..a24662c1dd --- /dev/null +++ b/chipsec/library/registers/msr.py @@ -0,0 +1,37 @@ +# CHIPSEC: Platform Security Assessment Framework +# Copyright (c) 2024, 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 +# + +''' +Main functionality to get the definition of IO registers +''' + +from chipsec.library.registers.baseregister import BaseRegister + +class MSR(BaseRegister): + def __init__(self, cs): + super(MSR, self).__init__(cs) + + def get_def(self, bar_name): + scope = self.cs.Cfg.get_scope(bar_name) + vid, device, bar, _ = self.cs.Cfg.convert_internal_scope(scope, bar_name) + if bar in self.cs.Cfg.IO_BARS[vid][device]: + return self.cs.Cfg.IO_BARS[vid][device][bar] + else: + return None \ No newline at end of file diff --git a/chipsec/library/registers/pcicfg.py b/chipsec/library/registers/pcicfg.py new file mode 100644 index 0000000000..6360c5dee9 --- /dev/null +++ b/chipsec/library/registers/pcicfg.py @@ -0,0 +1,37 @@ +# CHIPSEC: Platform Security Assessment Framework +# Copyright (c) 2024, 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 +# + +''' +Main functionality to get the definition of IO registers +''' + +from chipsec.library.registers.baseregister import BaseRegister + +class PCICfg(BaseRegister): + def __init__(self, cs): + super(PCICfg, self).__init__(cs) + + def get_def(self, bar_name): + scope = self.cs.Cfg.get_scope(bar_name) + vid, device, bar, _ = self.cs.Cfg.convert_internal_scope(scope, bar_name) + if bar in self.cs.Cfg.IO_BARS[vid][device]: + return self.cs.Cfg.IO_BARS[vid][device][bar] + else: + return None \ No newline at end of file