Skip to content

Commit e9e1aca

Browse files
committed
Update spi modules to use the correct spi instance
1 parent 02fab2a commit e9e1aca

11 files changed

Lines changed: 97 additions & 75 deletions

File tree

‎.github/workflows/tests.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ jobs:
323323
- name: Run chipsec_main test
324324
run: |
325325
PYTHONEXE="$(which python)"
326-
CHIPSECEXIT="$($(sudo ${PYTHONEXE} chipsec_main.py -p PMC_I440FX 1>&2); echo $?)"
326+
CHIPSECEXIT="$($(sudo ${PYTHONEXE} chipsec_main.py -p PMC_I440FX --mfgid GenuineIntel 1>&2); echo $?)"
327327
if echo "0 1 2 4 8" | grep -qw $CHIPSECEXIT; then $(exit 0); else $(exit $CHIPSECEXIT); fi
328328
329329
qemu-uefi-test:

‎chipsec/cfg/parsers/controls.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ def write(self, value: int) -> None:
140140
self.logger.log_error(error_msg)
141141
raise ControlError(error_msg) from e
142142

143+
def print(self) -> None:
144+
"""
145+
Print the current value of the control.
146+
"""
147+
self.logger.log(str(self))
148+
143149
def get_register_name(self) -> str:
144150
"""
145151
Get the name of the register containing this control.

‎chipsec/cfg/parsers/registers/controls.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,12 @@ def write(self, value: int) -> None:
192192
except Exception as e:
193193
raise ControlHelperError(f"Failed to write to control field '{self.field}' in register '{self.get_register_name()}': {e}") from e
194194

195+
def print(self) -> None:
196+
"""
197+
Print the current value of the control.
198+
"""
199+
self.logger.log(str(self))
200+
195201
def get_current_value(self) -> Optional[int]:
196202
"""
197203
Get the current cached value without reading from hardware.

‎chipsec/chipset.py‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def basic_init_with_helper(cls, helper=None):
121121
return _cs
122122

123123
def init(self, platform_code, req_pch_code, helper_name=None, start_helper=True,
124-
load_config=True, ignore_platform=False):
124+
load_config=True, ignore_platform=False, req_mfgid=None):
125125
"""Initialize the chipset with platform detection and configuration.
126126
127127
Args:
@@ -131,6 +131,7 @@ def init(self, platform_code, req_pch_code, helper_name=None, start_helper=True,
131131
start_helper: Whether to start the helper immediately
132132
load_config: Whether to load platform configuration
133133
ignore_platform: Whether to skip platform detection
134+
req_mfgid: Manufacturer ID to force instead of detecting it
134135
135136
Raises:
136137
UnknownChipsetError: If platform cannot be detected
@@ -152,14 +153,18 @@ def init(self, platform_code, req_pch_code, helper_name=None, start_helper=True,
152153

153154
# Platform detection
154155
cpuid = 0
156+
if req_mfgid:
157+
# Set before any HAL is resolved so HAL dispatch uses the forced value
158+
self.Cfg.set_mfgid(req_mfgid)
159+
self.logger.log_important(f'Forcing manufacturer ID to "{req_mfgid}"')
155160
if start_helper:
156161
self.load_helper(helper_name)
157162
self.start_helper()
158163
# Get CPUID only if using driver (otherwise it will cause problems)
159164
cpuid = self.get_cpuid()
160-
mfgid = self.get_mfgid()
161165
self.Cfg.set_cpuid(cpuid)
162-
self.Cfg.set_mfgid(mfgid)
166+
if not req_mfgid:
167+
self.Cfg.set_mfgid(self.get_mfgid())
163168
else:
164169
self.load_helper(NoneHelper())
165170

@@ -173,7 +178,8 @@ def init(self, platform_code, req_pch_code, helper_name=None, start_helper=True,
173178
# Seed a minimal topology so config parsers that reference CPU
174179
# (e.g. MSR scope handling) don't fail when running without a helper.
175180
self.Cfg.set_topology({'threads': 1, 'cores': {0: [0]}, 'packages': {0: [0]}})
176-
self.Cfg.set_mfgid(_MFGID_BY_VID.get(self.Cfg.vid, 'GenuineIntel'))
181+
if not req_mfgid:
182+
self.Cfg.set_mfgid(_MFGID_BY_VID.get(self.Cfg.vid, 'GenuineIntel'))
177183
if not ignore_platform:
178184
self.Cfg.platform_detection(platform_code, req_pch_code, cpuid)
179185
_unknown_proc = not bool(self.Cfg.get_chipset_code())

‎chipsec/modules/common/debugenabled.py‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,10 @@ def check_dci(self) -> int:
8181
self.logger.log_important('ECTRL register not found. Skipping DCI check.')
8282
return ModuleResult.WARNING
8383
ectrl.read_and_verbose_print()
84-
hdcien_mask = ectrl[0].get_field_mask('ENABLE', True)
8584

8685
if ectrl.is_all_field_value(ectrl[0].get_field('ENABLE'), 'ENABLE'):
8786
self.logger.log_good('CPU debug enable is set consistently')
88-
if ectrl.is_any_value(hdcien_mask, 'ENABLE'):
87+
if ectrl.is_any_field_value(1, "ENABLE"):
8988
self.logger.log_bad('DCI Debug is enabled')
9089
TestFail = ModuleResult.FAILED
9190
self.result.setStatusBit(self.result.status.DEBUG_FEATURE)

‎chipsec/modules/common/spi_access.py‎

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -72,55 +72,53 @@ def is_supported(self) -> bool:
7272
return False
7373

7474
def check_flash_access_permissions(self) -> int:
75-
frap_objs = self.cs.register.get_list_by_name('FRAP')
76-
frap_objs.read()
77-
for frap in frap_objs:
78-
self.logger.log_verbose(frap)
79-
fdv_obj = self.cs.register.get_instance_by_name('HSFS', frap.get_instance())
80-
fdv = fdv_obj.read_field('FDV') == 1
81-
brwa = frap.get_field('BRWA')
82-
83-
if not fdv:
84-
self.logger.log("[*] Flash Descriptor Valid bit is not set")
85-
86-
if brwa & (1 << PLATFORM_DATA):
87-
self.logger.log("[*] Software has write access to Platform Data region in SPI flash (it's platform specific)")
88-
89-
if brwa & (1 << GBE):
90-
self.update_res(ModuleResult.WARNING)
91-
self.result.setStatusBit(self.result.status.ACCESS_RW)
92-
self.logger.log_warning("Software has write access to GBe region in SPI flash")
93-
94-
if brwa & (1 << FLASH_DESCRIPTOR):
95-
self.update_res(ModuleResult.FAILED)
96-
self.result.setStatusBit(self.result.status.ACCESS_RW)
97-
self.logger.log_bad("Software has write access to SPI flash descriptor")
98-
99-
if brwa & (1 << ME):
100-
self.update_res(ModuleResult.FAILED)
101-
self.result.setStatusBit(self.result.status.ACCESS_RW)
102-
self.logger.log_bad("Software has write access to Management Engine (ME) region in SPI flash")
103-
104-
if fdv:
105-
if ModuleResult.PASSED == self.res:
106-
self.logger.log_good("SPI Flash Region Access Permissions in flash descriptor look ok")
107-
elif ModuleResult.FAILED == self.res:
108-
self.logger.log_failed('SPI Flash Region Access Permissions are not programmed securely in flash descriptor')
109-
self.logger.log_important('System may be using alternative protection by including descriptor region in SPI Protected Range Registers')
110-
self.logger.log_important('If using alternative protections, this can be considered a WARNING')
111-
elif ModuleResult.WARNING == self.res:
112-
self.logger.log_warning("Certain SPI flash regions are writeable by software")
113-
else:
114-
self.update_res(ModuleResult.WARNING)
115-
self.result.setStatusBit(self.result.status.UNSUPPORTED_FEATURE)
116-
self.logger.log_warning("Either flash descriptor is not valid or not present on this system")
75+
frap = self.cs.register.get_instance_by_name('FRAP', self.spi.instance)
76+
frap.read()
77+
brwa = frap.get_field('BRWA')
78+
fdv_obj = self.cs.register.get_instance_by_name('HSFS', self.spi.instance)
79+
fdv = fdv_obj.read_field('FDV') == 1
80+
81+
if not fdv:
82+
self.logger.log("[*] Flash Descriptor Valid bit is not set")
83+
84+
if brwa & (1 << PLATFORM_DATA):
85+
self.logger.log("[*] Software has write access to Platform Data region in SPI flash (it's platform specific)")
86+
87+
if brwa & (1 << GBE):
88+
self.update_res(ModuleResult.WARNING)
89+
self.result.setStatusBit(self.result.status.ACCESS_RW)
90+
self.logger.log_warning("Software has write access to GBe region in SPI flash")
91+
92+
if brwa & (1 << FLASH_DESCRIPTOR):
93+
self.update_res(ModuleResult.FAILED)
94+
self.result.setStatusBit(self.result.status.ACCESS_RW)
95+
self.logger.log_bad("Software has write access to SPI flash descriptor")
96+
97+
if brwa & (1 << ME):
98+
self.update_res(ModuleResult.FAILED)
99+
self.result.setStatusBit(self.result.status.ACCESS_RW)
100+
self.logger.log_bad("Software has write access to Management Engine (ME) region in SPI flash")
101+
102+
if fdv:
103+
if ModuleResult.PASSED == self.res:
104+
self.logger.log_good("SPI Flash Region Access Permissions in flash descriptor look ok")
105+
elif ModuleResult.FAILED == self.res:
106+
self.logger.log_failed('SPI Flash Region Access Permissions are not programmed securely in flash descriptor')
107+
self.logger.log_important('System may be using alternative protection by including descriptor region in SPI Protected Range Registers')
108+
self.logger.log_important('If using alternative protections, this can be considered a WARNING')
109+
elif ModuleResult.WARNING == self.res:
110+
self.logger.log_warning("Certain SPI flash regions are writeable by software")
111+
else:
112+
self.update_res(ModuleResult.WARNING)
113+
self.result.setStatusBit(self.result.status.UNSUPPORTED_FEATURE)
114+
self.logger.log_warning("Either flash descriptor is not valid or not present on this system")
117115

118116
return self.result.getReturnCode(self.res)
119117

120118
def run(self, module_argv: List[str]) -> int:
121119
self.logger.start_test('SPI Flash Region Access Control')
122120
try:
123-
self.spi = SPI(self.cs)
121+
self.spi = self.cs.hals.spi
124122
self.spi.display_SPI_Ranges_Access_Permissions()
125123
self.res = self.check_flash_access_permissions()
126124
except CSReadError as err:

‎chipsec/modules/common/spi_desc.py‎

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
4040
"""
4141

42-
from chipsec.library.exceptions import CSReadError
42+
from chipsec.library.exceptions import CSReadError, HALInitializationError
4343
from chipsec.module_common import BaseModule, BIOS
4444
from chipsec.library.returncode import ModuleResult
4545
from chipsec.library.intel.spi import FLASH_DESCRIPTOR
@@ -58,25 +58,29 @@ def __init__(self):
5858
})
5959

6060
def is_supported(self) -> bool:
61-
if self.cs.register.has_all_fields('FRAP', ['BRRA', 'BRWA']):
61+
try:
62+
instance = self.cs.hals.spi.instance
63+
except (CSReadError, HALInitializationError):
64+
self.logger.log_important('Unable to read SPI instance. Skipping module.')
65+
return False
66+
self.frap = self.cs.register.get_instance_by_name('FRAP', instance)
67+
if self.frap and self.frap.has_all_fields(['BRRA', 'BRWA']):
6268
return True
63-
self.logger.log_important('FRAP.BRWA or FRAP.BRRA registers not defined for platform. Skipping module.')
69+
self.logger.log_important('FRAP register or FRAP.BRWA/FRAP.BRRA fields not defined for platform. Skipping module.')
6470
return False
6571

6672
def check_flash_access_permissions(self) -> int:
67-
6873
res = ModuleResult.PASSED
69-
frap_registers = self.cs.register.get_list_by_name('FRAP')
70-
frap_registers.read_and_print()
71-
for frap in frap_registers:
72-
brra = frap.get_field('BRRA')
73-
brwa = frap.get_field('BRWA')
74-
75-
self.logger.log(f'[*] Software access to SPI flash regions: read = 0x{brra:02X}, write = 0x{brwa:02X}')
76-
if brwa & (1 << FLASH_DESCRIPTOR):
77-
res = ModuleResult.FAILED
78-
self.result.setStatusBit(self.result.status.ACCESS_RW)
79-
self.logger.log_bad('Software has write access to SPI flash descriptor')
74+
self.frap.read()
75+
self.frap.print()
76+
brra = self.frap.get_field('BRRA')
77+
brwa = self.frap.get_field('BRWA')
78+
79+
self.logger.log(f'[*] Software access to SPI flash regions: read = 0x{brra:02X}, write = 0x{brwa:02X}')
80+
if brwa & (1 << FLASH_DESCRIPTOR):
81+
res = ModuleResult.FAILED
82+
self.result.setStatusBit(self.result.status.ACCESS_RW)
83+
self.logger.log_bad('Software has write access to SPI flash descriptor')
8084

8185
self.logger.log('')
8286
if ModuleResult.PASSED == res:

‎chipsec/modules/common/spi_lock.py‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ def __init__(self):
5858
super(spi_lock, self).__init__()
5959

6060
def is_supported(self) -> bool:
61-
# breakpoint()
6261
if self.cs.control.is_defined('FlashLockDown'):
6362
return True
6463
self.logger.log_important('FlashLockDown control not define for platform. Skipping module.')
@@ -67,18 +66,20 @@ def is_supported(self) -> bool:
6766
def check_spi_lock(self) -> int:
6867
res = ModuleResult.PASSED
6968
if self.cs.control.is_defined('SpiWriteStatusDis'):
70-
wrsdis = self.cs.control.get_list_by_name('SpiWriteStatusDis')
71-
wrsdis.read_and_print()
72-
if wrsdis.is_all_value(1):
69+
wrsdis = self.cs.control.get_instance_by_name('SpiWriteStatusDis', self.cs.hals.spi.instance)
70+
wsrdis_value = wrsdis.read()
71+
wrsdis.print()
72+
if wsrdis_value == 1:
7373
self.logger.log_good('SPI write status disable set.')
7474
else:
7575
res = ModuleResult.FAILED
7676
self.result.setStatusBit(self.result.status.ACCESS_RW)
7777
self.logger.log_bad('SPI write status disable not set.')
7878

79-
flockdn = self.cs.control.get_list_by_name('FlashLockDown')
80-
flockdn.read_and_print()
81-
if flockdn.is_all_value(1):
79+
flockdn = self.cs.control.get_instance_by_name('FlashLockDown', self.cs.hals.spi.instance)
80+
vlockdn_value = flockdn.read()
81+
flockdn.print()
82+
if vlockdn_value == 1:
8283
self.logger.log_good('SPI Flash Controller configuration is locked')
8384
else:
8485
res = ModuleResult.FAILED

‎chipsec_main.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def parse_args(argv: Sequence[str]) -> Optional[Dict[str, Any]]:
7878
adv_options.add_argument('-p', '--platform', dest='_platform', help='Explicitly specify platform code',
7979
choices=list(chipset.cs().Cfg.get_supported_platforms()), type=str.upper)
8080
adv_options.add_argument('--pch', dest='_pch', help='Explicitly specify PCH code', choices=list(chipset.cs().Cfg.get_supported_pchs()), type=str.upper)
81+
adv_options.add_argument('--mfgid', dest='_mfgid', help='Force the CPU manufacturer ID instead of detecting it', choices=['GenuineIntel', 'AuthenticAMD'])
8182
adv_options.add_argument('-n', '--no_driver', dest='_no_driver', action='store_true',
8283
help="Chipsec won't need kernel mode functions so don't load chipsec driver")
8384
adv_options.add_argument('-i', '--ignore_platform', dest='_ignore_platform', action='store_true',
@@ -436,7 +437,7 @@ def main(self) -> int:
436437
sys.path.append(os.path.abspath(import_path))
437438

438439
try:
439-
self._cs.init(self._platform, self._pch, self._helper, not self._no_driver, self._load_config, self._ignore_platform)
440+
self._cs.init(self._platform, self._pch, self._helper, not self._no_driver, self._load_config, self._ignore_platform, self._mfgid)
440441
except UnknownChipsetError as msg:
441442
self.logger.log_error(f'Platform is not supported ({str(msg)}).')
442443
if self._ignore_platform:

‎chipsec_util.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def parse_args(argv: Sequence[str]) -> Optional[Dict[str, Any]]:
9393
options.add_argument('-l', '--log', help='Output to log file')
9494
options.add_argument('-p', '--platform', dest='_platform', help='Explicitly specify platform code', choices=list(cs().Cfg.get_supported_platforms()), type=str.upper)
9595
options.add_argument('--pch', dest='_pch', help='Explicitly specify PCH code', choices=list(cs().Cfg.get_supported_pchs()), type=str.upper)
96+
options.add_argument('--mfgid', dest='_mfgid', help='Force the CPU manufacturer ID instead of detecting it', choices=['GenuineIntel', 'AuthenticAMD'])
9697
options.add_argument('-n', '--no_driver', dest='_no_driver', action='store_true',
9798
help="Chipsec won't need kernel mode functions so don't load chipsec driver")
9899
options.add_argument('-i', '--ignore_platform', dest='_ignore_platform', action='store_true',
@@ -163,7 +164,7 @@ def main(self) -> int:
163164
return ExitCode.ERROR
164165

165166
try:
166-
self._cs.init(self._platform, self._pch, self._helper, reqs.load_driver(), reqs.load_config(), self._ignore_platform)
167+
self._cs.init(self._platform, self._pch, self._helper, reqs.load_driver(), reqs.load_config(), self._ignore_platform, self._mfgid)
167168
except UnknownChipsetError as msg:
168169
self.logger.log_error(f'Platform is not supported ({str(msg)}).')
169170
self.logger.log_error('To specify a cpu please use -p command-line option')

0 commit comments

Comments
 (0)