Skip to content

Commit 643e61e

Browse files
committed
Enable bios_wp module to run successfully on ADL
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
1 parent 85027d4 commit 643e61e

File tree

9 files changed

+182
-128
lines changed

9 files changed

+182
-128
lines changed

chipsec/config.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#
2020

2121
from collections import namedtuple
22+
from collections.abc import Iterable
2223
from fnmatch import fnmatch
2324
import importlib
2425
import re
@@ -506,6 +507,41 @@ def convert_internal_scope(self, scope, name):
506507
else:
507508
sname = name
508509
return scope_name(*(sname.split('.', 3)))
510+
511+
def get_objlist(self, objdict:dict, name:str):
512+
scope = self.get_scope(name)
513+
fullscope = self.convert_internal_scope(scope, name)
514+
return self.get_objlist_from_scope(objdict, fullscope)
515+
516+
def __add_obj_to_regdef(self, reg_def, obj):
517+
if isinstance(obj, Iterable):
518+
reg_def.extend(obj)
519+
else:
520+
reg_def.append(obj)
521+
return reg_def
522+
523+
#'vid', 'parent', 'register', 'field'; register.get_obj("8086.*.FREG*_BIOS")
524+
def get_objlist_from_scope(self, objdict:dict, scope:scope_name):
525+
reg_def = ObjList()
526+
vid = scope.vid.replace('*', '.*')
527+
dict_vids = [vid] if '*' not in vid and vid in objdict.keys() else objdict.keys()
528+
for dict_vid in dict_vids:
529+
if re.match(vid, dict_vid):
530+
parent = scope.parent.replace('*', '.*')
531+
dict_parents = [parent] if '*' not in parent and parent in objdict[dict_vid].keys() else objdict[dict_vid].keys()
532+
for dict_parent in dict_parents:
533+
if re.match(parent, dict_parent):
534+
if scope.name:
535+
name = scope.name.replace('*', '.*')
536+
dict_names = [name] if '*' not in name and name in objdict[dict_vid][dict_parent].keys() else objdict[dict_vid][dict_parent].keys()
537+
for dict_name in dict_names:
538+
if re.match(name, dict_name):
539+
self.__add_obj_to_regdef(reg_def, objdict[dict_vid][dict_parent][dict_name])
540+
else:
541+
542+
self.__add_obj_to_regdef(reg_def, objdict[dict_vid][dict_parent])
543+
544+
return reg_def
509545

510546
# TODO: Review for correctness compared to chipsec/library/control.py:get_list_by_name()
511547
# def get_control_obj(self, control_name, instance=None):

chipsec/hal/common/memrange.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,9 @@ def write(self, phys_address: int, length: int, buf: bytes) -> int:
6262

6363
def get_def(self, range_name: str) -> Dict[str, Any]:
6464
'''Return address access of a MEM register'''
65-
scope = self.cs.Cfg.get_scope(range_name)
66-
vid, range, _, _ = self.cs.Cfg.convert_internal_scope(scope, range_name)
67-
if vid in self.cs.Cfg.MEMORY_RANGES and range in self.cs.Cfg.MEMORY_RANGES[vid]:
68-
return self.cs.Cfg.MEMORY_RANGES[vid][range]
65+
ranges = self.cs.Cfg.get_objlist(self.cs.Cfg.MEMORY_RANGES, range_name)
66+
if ranges:
67+
return ranges[0]
6968
return None
7069

7170

chipsec/hal/common/mmio.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,22 +207,31 @@ def get_MMIO_BAR_base_address(self, bar_name: str, pciobj: Optional[int] = None)
207207
size = 0
208208
mmioaddr = 0
209209

210-
if bar.register and pciobj is not None:
210+
if bar.register:
211+
211212
preserve = True
212-
bar_reg = self.cs.register.get_instance_by_name(bar.register, pciobj)
213-
if bar_reg:
213+
if pciobj is not None:
214+
bar_reg_list = [self.cs.register.get_instance_by_name(bar.register, pciobj)]
215+
else:
216+
bar_reg_list = self.cs.register.get_list_by_name(bar.register)
217+
218+
for bar_reg in bar_reg_list:
219+
# if bar_reg:
214220
if bar.reg_align:
215221
preserve = False
216222
if bar.base_field:
217223
base_field = bar.base_field
218224
try:
219225
base = bar_reg.read_field(base_field, preserve)
220226
except CSReadError:
221-
self.logger.log_hal('[mmio] Unable to determine MMIO Base register. Using Base = 0x0')
227+
continue
228+
# self.logger.log_hal('[mmio] Unable to determine MMIO Base register. Using Base = 0x0')
222229
try:
223230
reg_mask = bar_reg.get_field_mask(base_field, preserve)
224231
except CSReadError:
225-
self.logger.log_hal('[mmio] Unable to determine MMIO Mask register. Using Mask = 0xFFFF')
232+
continue
233+
# self.logger.log_hal('[mmio] Unable to determine MMIO Mask register. Using Mask = 0xFFFF')
234+
break
226235
if not preserve:
227236
base <<= bar.reg_align
228237
reg_mask <<= bar.reg_align
@@ -286,6 +295,7 @@ def get_MMIO_BAR_base_address(self, bar_name: str, pciobj: Optional[int] = None)
286295
size = DEFAULT_MMIO_BAR_SIZE
287296
self.logger.log_hal('[mmio] {}: 0x{:016X} (size = 0x{:X})'.format(bar_name, base, size))
288297
if base == 0:
298+
breakpoint()
289299
self.logger.log_hal('[mmio] Base address was determined to be 0.')
290300
raise CSReadError('[mmio] Base address was determined to be 0')
291301

chipsec/hal/common/physmem.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,9 @@ def get_value_from_bit_def(self, inputValue, fieldStartBit, fieldSize):
172172

173173
def get_def(self, range_name: str) -> Dict[str, Any]:
174174
'''Return address access of a MEM register'''
175-
scope = self.cs.Cfg.get_scope(range_name)
176-
vid, range, _, _ = self.cs.Cfg.convert_internal_scope(scope, range_name)
177-
if vid in self.cs.Cfg.MEMORY_RANGES and range in self.cs.Cfg.MEMORY_RANGES[vid]:
178-
return self.cs.Cfg.MEMORY_RANGES[vid][range]
175+
ranges = self.cs.Cfg.get_objlist(self.cs.Cfg.MEMORY_RANGES, range_name)
176+
if ranges:
177+
return ranges[0]
179178
return None
180179

181180

chipsec/hal/intel/spi.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ class SPI(hal_base.HALBase):
197197

198198
def __init__(self, cs):
199199
super(SPI, self).__init__(cs)
200-
self.instance = 0
200+
spidev = cs.device.get_obj('8086.SPI')
201+
self.instance = spidev.instances[0]
201202
self.mmio = cs.hals.MMIO
202203
self.get_registers()
203204
# self.rcba_spi_base = self.get_SPI_MMIO_base()
@@ -316,28 +317,29 @@ def get_SPI_regions(self, all_regions: bool = True) -> SpiRegions:
316317
spi_regions[r] = (range_base, range_limit, range_size, SPI_REGION_NAMES[r], freg)
317318
return spi_regions
318319

320+
319321
def get_SPI_Protected_Range(self, pr_num: int) -> Tuple[int, int, int, int, int, int]:
320322
if pr_num > SPI_MAX_PR_COUNT:
321323
return (0, 0, 0, 0, 0, 0)
322324

323-
pr_name = f'PR{pr_num:x}'
324-
pr_j_reg = self.cs.register.get_def(pr_name)['offset']
325-
pr_j = self.cs.register.read(pr_name)
325+
pr_name = f'8086.SPI.PR*'
326+
pr_j_reg = self.cs.register.get_instance_by_name(pr_name, self.instance)
327+
pr_j = pr_j_reg.read()
326328

327329
# Protected Range Base corresponds to FLA bits 24:12
328-
base = self.cs.register.get_field(pr_name, pr_j, 'PRB') << SPI_FLA_SHIFT
330+
base = pr_j_reg.get_field('PRB') << SPI_FLA_SHIFT
329331
# Protected Range Limit corresponds to FLA bits 24:12
330-
limit = self.cs.register.get_field(pr_name, pr_j, 'PRL') << SPI_FLA_SHIFT
332+
limit = pr_j_reg.get_field('PRL') << SPI_FLA_SHIFT
331333

332-
wpe = (0 != self.cs.register.get_field(pr_name, pr_j, 'WPE'))
333-
rpe = (0 != self.cs.register.get_field(pr_name, pr_j, 'RPE'))
334+
wpe = (0 != pr_j_reg.get_field('WPE'))
335+
rpe = (0 != pr_j_reg.get_field('RPE'))
334336

335337
# Check if this is a valid PRx config
336338
if wpe or rpe:
337339
# FLA bits 11:0 are assumed to be FFFh for the limit comparison
338340
limit |= SPI_FLA_PAGE_MASK
339341

340-
return (base, limit, wpe, rpe, pr_j_reg, pr_j)
342+
return (base, limit, wpe, rpe, pr_j_reg.offset, pr_j)
341343

342344
##############################################################################################################
343345
# SPI configuration

chipsec/library/device.py

Lines changed: 66 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -30,68 +30,78 @@ def __init__(self, cs) -> None:
3030
self.cs = cs
3131

3232
def get_obj(self, device_name: str) -> PCIConfig:
33-
scope = self.cs.Cfg.get_scope(device_name)
34-
vid, device, _, _ = self.cs.Cfg.convert_internal_scope(scope, device_name)
35-
if vid in self.cs.Cfg.CONFIG_PCI and device in self.cs.Cfg.CONFIG_PCI[vid]:
36-
return self.cs.Cfg.CONFIG_PCI[vid][device]
37-
else:
38-
return None
39-
40-
def get_first_bus(self, device: dict) -> int:
41-
"""Retrieves first value in bus list for PCI device"""
42-
if 'bus' in device:
43-
return self.get_first(device['bus'])
44-
raise CSBusNotFoundError()
45-
46-
def get_first(self, a_list: Union[list, int]) -> int:
47-
"""Returns received integer or first item from received list"""
48-
if type(a_list) is int:
49-
return a_list
50-
if type(a_list) is list:
51-
return a_list[0]
52-
raise CSFirstNotFoundError()
53-
54-
def get_BDF(self, device_name: str) -> Tuple[int, int, int]:
55-
"""Retrieves bus, device, and function values from PCI device"""
56-
scope = self.cs.Cfg.get_scope(device_name)
57-
vid, device, _, _ = self.cs.Cfg.convert_internal_scope(scope, device_name)
58-
try:
59-
device = self.cs.Cfg.CONFIG_PCI[vid][device]
60-
except KeyError:
61-
device = None
62-
if device is None or device == {}:
63-
raise DeviceNotFoundError(f'DeviceNotFound: {device_name}')
64-
b = device['bus']
65-
d = device['dev']
66-
f = device['fun']
67-
return (b, d, f)
68-
69-
def get_VendorID(self, device_name: str) -> Tuple[int, int]:
70-
"""Retrieves device ID and vendor ID from the PCI device"""
71-
(b, d, f) = self.get_BDF(device_name)
72-
return self.cs.hals.Pci.get_DIDVID(b, d, f)
73-
74-
def is_enabled(self, device_name: str) -> bool:
75-
"""Checks if PCI device is enabled"""
76-
if self.is_defined(device_name):
77-
(b, d, f) = self.get_BDF(device_name)
78-
return self.cs.hals.Pci.is_enabled(b, d, f)
79-
return False
33+
devlist = self.get_objlist(device_name)
34+
if devlist:
35+
return devlist[0]
36+
return None
37+
38+
def get_objlist(self, device_name: str):
39+
return self.cs.Cfg.get_objlist(self.cs.Cfg.CONFIG_PCI, device_name)
40+
41+
# def get_first_bus(self, device: dict) -> int:
42+
# """Retrieves first value in bus list for PCI device"""
43+
# if 'bus' in device:
44+
# return self.get_first(device['bus'])
45+
# raise CSBusNotFoundError()
46+
47+
# def get_first(self, a_list: Union[list, int]) -> int:
48+
# """Returns received integer or first item from received list"""
49+
# if type(a_list) is int:
50+
# return a_list
51+
# if type(a_list) is list:
52+
# return a_list[0]
53+
# raise CSFirstNotFoundError()
54+
55+
# def get_BDF(self, device_name: str) -> Tuple[int, int, int]:
56+
# """Retrieves bus, device, and function values from PCI device"""
57+
# scope = self.cs.Cfg.get_scope(device_name)
58+
# vid, device, _, _ = self.cs.Cfg.convert_internal_scope(scope, device_name)
59+
# try:
60+
# device = self.cs.Cfg.CONFIG_PCI[vid][device]
61+
# except KeyError:
62+
# device = None
63+
# if device is None or device == {}:
64+
# raise DeviceNotFoundError(f'DeviceNotFound: {device_name}')
65+
# b = device['bus']
66+
# d = device['dev']
67+
# f = device['fun']
68+
# return (b, d, f)
69+
70+
# def get_VendorID(self, device_name: str) -> Tuple[int, int]:
71+
# """Retrieves device ID and vendor ID from the PCI device"""
72+
# (b, d, f) = self.get_BDF(device_name)
73+
# return self.cs.hals.Pci.get_DIDVID(b, d, f)
74+
75+
# def is_enabled(self, device_name: str) -> bool:
76+
# """Checks if PCI device is enabled"""
77+
# if self.is_defined(device_name):
78+
# (b, d, f) = self.get_BDF(device_name)
79+
# return self.cs.hals.Pci.is_enabled(b, d, f)
80+
# return False
8081

8182
def is_defined(self, device_name: str) -> bool:
8283
"""Checks if device is defined in the XML config"""
83-
scope = self.cs.Cfg.get_scope(device_name)
84-
vid, device, _, _ = self.cs.Cfg.convert_internal_scope(scope, device_name)
85-
return self.cs.Cfg.CONFIG_PCI[vid].get(device, None) is not None
84+
return self.get_obj(device_name) is not None
85+
# scope = self.cs.Cfg.get_scope(device_name)
86+
# vid, device, _, _ = self.cs.Cfg.convert_internal_scope(scope, device_name)
87+
# return self.cs.Cfg.CONFIG_PCI[vid].get(device, None) is not None
8688

8789
def get_bus(self, device_name: str) -> List[int]:
8890
"""Retrieves bus value(s) from PCI device"""
89-
scope = self.cs.Cfg.get_scope(device_name)
90-
vid, device, _, _ = self.cs.Cfg.convert_internal_scope(scope, device_name)
91-
if vid in self.cs.Cfg.CONFIG_PCI and device in self.cs.Cfg.CONFIG_PCI[vid]:
92-
return self.cs.Cfg.CONFIG_PCI[vid][device].bus
93-
else:
94-
return []
91+
dev_list = self.get_objlist(device_name)
92+
buses = []
93+
breakpoint()
94+
for dev in dev_list:
95+
for instance_key in dev.instances.keys():
96+
buses.append(dev.instances[instance_key].bus)
97+
return buses
98+
99+
# scope = self.cs.Cfg.get_scope(device_name)
100+
# vid, device, _, _ = self.cs.Cfg.convert_internal_scope(scope, device_name)
101+
# if vid in self.cs.Cfg.CONFIG_PCI and device in self.cs.Cfg.CONFIG_PCI[vid]:
102+
# return self.cs.Cfg.CONFIG_PCI[vid][device].bus
103+
# else:
104+
# return []
95105

96106
# buses = self.cs.Cfg.BUS.get(device_name, [])
97107
# if buses:

chipsec/library/register.py

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -119,33 +119,26 @@ def get_def(self, reg_name: str) -> Dict[str, Any]:
119119

120120
# rework any call to this function
121121
def get_list_by_name(self, reg_name: str) -> 'ObjList':
122-
reg_def = ObjList()
123-
scope = self.cs.Cfg.get_scope(reg_name)
124-
vid, dev_name, register, _ = self.cs.Cfg.convert_internal_scope(scope, reg_name)
125-
if vid in self.cs.Cfg.REGISTERS and dev_name in self.cs.Cfg.REGISTERS[vid] and register in self.cs.Cfg.REGISTERS[vid][dev_name]:
126-
reg_def.extend(self.cs.Cfg.REGISTERS[vid][dev_name][register])
127-
return reg_def
122+
return self.cs.Cfg.get_objlist(self.cs.Cfg.REGISTERS, reg_name)
123+
124+
def get_list_by_name_without_scope(self, reg_name: str) -> 'ObjList':
125+
return self.cs.Cfg.get_objlist(self.cs.Cfg.REGISTERS, "*.*." + reg_name)
128126

129127
def get_instance_by_name(self, reg_name: str, instance: Any):
130-
scope = self.cs.Cfg.get_scope(reg_name)
131-
vid, dev_name, register, _ = self.cs.Cfg.convert_internal_scope(scope, reg_name)
132-
if vid in self.cs.Cfg.REGISTERS and dev_name in self.cs.Cfg.REGISTERS[vid] and register in self.cs.Cfg.REGISTERS[vid][dev_name]:
133-
for reg_obj in self.cs.Cfg.REGISTERS[vid][dev_name][register]:
134-
if reg_obj.instance == instance:
135-
return reg_obj
128+
for reg_obj in self.cs.Cfg.get_objlist(self.cs.Cfg.REGISTERS, reg_name):
129+
if reg_obj.instance == instance:
130+
return reg_obj
136131
return None #TODO Change to null register object
137132

138133
def has_field(self, reg_name: str, field_name: str) -> bool:
139-
scope = self.cs.Cfg.get_scope(reg_name)
140-
vid, device, register, _ = self.cs.Cfg.convert_internal_scope(scope, reg_name)
141134
"""Checks if the register has specific field"""
142-
scope = self.cs.Cfg.get_scope(reg_name)
143-
vid, device, register, _ = self.cs.Cfg.convert_internal_scope(scope, reg_name)
144-
try:
145-
reg_def = self.cs.Cfg.REGISTERS[vid][device][register]
146-
except KeyError:
147-
return False
148-
return field_name in reg_def[0].fields
135+
reg_defs = self.cs.Cfg.get_objlist(self.cs.Cfg.REGISTERS, reg_name)
136+
for reg_def in reg_defs:
137+
try:
138+
return field_name in reg_def.fields
139+
except KeyError:
140+
return False
141+
return False
149142

150143
def get_match(self, name: str):
151144
vid, device, register, field = self.cs.Cfg.convert_internal_scope("", name)

0 commit comments

Comments
 (0)