mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-05-04 06:26:54 +00:00
This patch is to generates frequency limits for each CPU, as a set of data structure in hypervisor .c code. With the frequency limits data, the hypervisor performance manager does not have to deal with the CPU/board info. It just choose the highest/lowest/guaranteed performance level and performance/nominal p-state, and use them to construct HWP_REQUEST/PERF_CTL reg value. How are frequency limits decided: - For CPUs in standard VMs, frequency limits are just decided by CPU/board info. - For CPUs assigned to RTVMs, we want certainty in latency, so just set its frequency to nominal/guaranteed by letting highest=lowest. - In some cases, CPUs are sharing frequency on hardware level (e.g. ADL e-cores in group of 4). This is described as _PSD in ACPI spec, or 'frequency domain' in Linux cpufreq driver. Thoese CPUs' frequency are linked together. If one of them are running RTVM, all other CPUs in the domain should be set to the same frequency. Tracked-On: #8168 Signed-off-by: Wu Zhou <wu.zhou@intel.com> Reviewed-by: Junjie Mao <junjie.mao@intel.com>
763 lines
23 KiB
Python
763 lines
23 KiB
Python
# Copyright (C) 2019-2022 Intel Corporation.
|
|
#
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
|
|
import re
|
|
import sys
|
|
import common
|
|
import collections
|
|
|
|
BOARD_NAME = ''
|
|
BIOS_INFO = ['BIOS Information', 'Vendor:', 'Version:', 'Release Date:', 'BIOS Revision:']
|
|
BASE_BOARD = ['Base Board Information', 'Manufacturer:', 'Product Name:', 'Version:']
|
|
|
|
LEGACY_TTYS = {
|
|
'ttyS0':'0x3F8',
|
|
'ttyS1':'0x2F8',
|
|
'ttyS2':'0x3E8',
|
|
'ttyS3':'0x2E8',
|
|
}
|
|
|
|
VALID_LEGACY_IRQ = []
|
|
ERR_LIST = {}
|
|
USED_RAM_RANGE = {}
|
|
|
|
HEADER_LICENSE = common.open_license() + "\n"
|
|
|
|
# The data base contains hide pci device
|
|
KNOWN_HIDDEN_PDEVS_BOARD_DB = {
|
|
'apl-mrb':['00:0d:0'],
|
|
'apl-up2':['00:0d:0'],
|
|
}
|
|
|
|
TSN_DEVS = ["8086:4b30", "8086:4b31", "8086:4b32", "8086:4ba0", "8086:4ba1", "8086:4ba2",
|
|
"8086:4bb0", "8086:4bb1", "8086:4bb2", "8086:a0ac", "8086:43ac", "8086:43a2"]
|
|
GPIO_DEVS = ["8086:4b88", "8086:4b89"]
|
|
TPM_PASSTHRU_BOARD = ['whl-ipc-i5', 'whl-ipc-i7', 'tgl-rvp', 'ehl-crb-b', 'cfl-k700-i7']
|
|
|
|
KNOWN_CAPS_PCI_DEVS_DB = {
|
|
"VMSIX":TSN_DEVS + GPIO_DEVS,
|
|
}
|
|
|
|
P2SB_PASSTHRU_BOARD = ('ehl-crb-b')
|
|
|
|
def get_info(board_info, msg_s, msg_e):
|
|
"""
|
|
Get information which specify by argument
|
|
:param board_info: it is a file what contains information for script to read from
|
|
:param msg_s: it is a pattern of key stings what start to match from board information
|
|
:param msg_e: it is a pattern of key stings what end to match from board information
|
|
"""
|
|
info_start = False
|
|
info_end = False
|
|
info_lines = []
|
|
num = len(msg_s.split())
|
|
|
|
with open(board_info, 'rt') as f_board:
|
|
while True:
|
|
|
|
line = f_board.readline()
|
|
if not line:
|
|
break
|
|
|
|
if " ".join(line.split()[0:num]) == msg_s:
|
|
info_start = True
|
|
info_end = False
|
|
continue
|
|
|
|
if " ".join(line.split()[0:num]) == msg_e:
|
|
info_start = False
|
|
info_end = True
|
|
continue
|
|
|
|
if info_start and not info_end:
|
|
info_lines.append(line)
|
|
continue
|
|
|
|
if not info_start and info_end:
|
|
return info_lines
|
|
|
|
|
|
def handle_bios_info(config):
|
|
"""
|
|
Handle bios information
|
|
:param config: it is a file pointer of bios information for writing to
|
|
"""
|
|
bios_lines = get_info(common.BOARD_INFO_FILE, "<BIOS_INFO>", "</BIOS_INFO>")
|
|
board_lines = get_info(common.BOARD_INFO_FILE, "<BASE_BOARD_INFO>", "</BASE_BOARD_INFO>")
|
|
print("/*", file=config)
|
|
|
|
if not bios_lines or not board_lines:
|
|
print(" * DMI info is not found", file=config)
|
|
else:
|
|
i_cnt = 0
|
|
bios_board = BIOS_INFO + BASE_BOARD
|
|
|
|
# remove the same value and keep origin sort
|
|
bios_board_info = list(set(bios_board))
|
|
bios_board_info.sort(key=bios_board.index)
|
|
|
|
bios_board_lines = bios_lines + board_lines
|
|
bios_info_len = len(bios_lines)
|
|
for line in bios_board_lines:
|
|
if i_cnt == bios_info_len:
|
|
print(" *", file=config)
|
|
|
|
i_cnt += 1
|
|
|
|
for misc_info in bios_board_info:
|
|
if misc_info == " ".join(line.split()[0:1]) or misc_info == \
|
|
" ".join(line.split()[0:2]) or misc_info == " ".join(line.split()[0:3]):
|
|
print(" * {0}".format(line.strip()), file=config)
|
|
|
|
print(" */", file=config)
|
|
|
|
|
|
def handle_root_dev(line):
|
|
"""Handle if it match root device information pattern
|
|
:param line: one line of information which had decoded to 'ASCII'
|
|
"""
|
|
for root_type in line.split():
|
|
# only support ext4 rootfs
|
|
if "ext4" in root_type:
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def get_max_clos_mask(board_file):
|
|
"""
|
|
Parse CLOS information
|
|
:param board_file: it is a file what contains board information for script to read from
|
|
:return: type of rdt resource supported and their corresponding clos max.
|
|
"""
|
|
rdt_res=[]
|
|
rdt_res_clos_max=[]
|
|
rdt_res_mask_max=[]
|
|
|
|
clos_lines = get_info(board_file, "<CLOS_INFO>", "</CLOS_INFO>")
|
|
for line in clos_lines:
|
|
if line.split(':')[0].strip() == "rdt resources supported":
|
|
rdt_res = line.split(':')[1].strip()
|
|
elif line.split(':')[0].strip() == "rdt resource clos max":
|
|
rdt_res_clos_max = line.split(':')[1].strip()
|
|
elif line.split(':')[0].strip() == "rdt resource mask max":
|
|
rdt_res_mask_max = line.split(':')[1].strip()
|
|
|
|
if (len(rdt_res) == 0) or (len(rdt_res_clos_max) == 0):
|
|
return rdt_res, rdt_res_clos_max, rdt_res_mask_max
|
|
else:
|
|
return list(re.split(', |\s |,', rdt_res)), list(map(int, rdt_res_clos_max.split(','))), list(re.split(', |\s |,', rdt_res_mask_max))
|
|
|
|
|
|
def get_rootfs(config_file):
|
|
"""
|
|
This will get rootfs partition from board information
|
|
:param config_file: it is a file which contain board information
|
|
:return: rootfs partition list
|
|
"""
|
|
root_dev_list = []
|
|
rootfs_lines = get_info(config_file, "<BLOCK_DEVICE_INFO>", "</BLOCK_DEVICE_INFO>")
|
|
|
|
# none 'BLOCK_DEVICE_INFO' tag
|
|
if rootfs_lines == None:
|
|
return root_dev_list
|
|
|
|
for rootfs_line in rootfs_lines:
|
|
if not rootfs_line:
|
|
break
|
|
|
|
if not handle_root_dev(rootfs_line):
|
|
continue
|
|
|
|
root_dev = rootfs_line.strip().split(':')[0]
|
|
root_dev_list.append(root_dev)
|
|
|
|
return (root_dev_list, len(root_dev_list))
|
|
|
|
|
|
def clos_info_parser(board_info):
|
|
""" Parse CLOS information """
|
|
return get_max_clos_mask(board_info)
|
|
|
|
|
|
def get_valid_irq(board_info):
|
|
"""
|
|
This is get available irq from board info file
|
|
:param board_info: it is a file what contains board information for script to read from
|
|
:return: None
|
|
"""
|
|
global VALID_LEGACY_IRQ
|
|
val_irq = []
|
|
irq_info_lines = get_info(board_info, "<AVAILABLE_IRQ_INFO>", "</AVAILABLE_IRQ_INFO>")
|
|
for irq_string in irq_info_lines:
|
|
val_irq = [x.strip() for x in irq_string.split(',')]
|
|
|
|
VALID_LEGACY_IRQ = val_irq
|
|
|
|
|
|
def alloc_irq():
|
|
"""
|
|
This is allocated an available irq
|
|
:return: free irq
|
|
"""
|
|
irq_val = VALID_LEGACY_IRQ.pop(0)
|
|
|
|
return irq_val
|
|
|
|
|
|
def parser_hv_console():
|
|
"""
|
|
There may be 3 types in the console item
|
|
1. BDF:(00:18.2) seri:/dev/ttyS2
|
|
2. /dev/ttyS2
|
|
3. ttyS2
|
|
"""
|
|
ttys_n = ''
|
|
err_dic = {}
|
|
ttys = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "DEBUG_OPTIONS", "SERIAL_CONSOLE")
|
|
|
|
if not ttys or ttys == None:
|
|
return (err_dic, ttys_n)
|
|
|
|
if ttys and 'BDF' in ttys or '/dev' in ttys:
|
|
ttys_n = ttys.split('/')[2]
|
|
else:
|
|
ttys_n = ttys
|
|
|
|
return (err_dic, ttys_n)
|
|
|
|
|
|
def get_processor_info():
|
|
"""
|
|
Get cpu processor list
|
|
:param board_info: it is a file what contains board information
|
|
:return: cpu processor list
|
|
"""
|
|
processor_list = []
|
|
tmp_list = []
|
|
processor_info = get_info(common.BOARD_INFO_FILE, "<CPU_PROCESSOR_INFO>", "</CPU_PROCESSOR_INFO>")
|
|
|
|
if not processor_info:
|
|
key = "CPU PROCESSOR_INFO error:"
|
|
ERR_LIST[key] = "CPU core is not exists"
|
|
return processor_list
|
|
|
|
for processor_line in processor_info:
|
|
if not processor_line:
|
|
break
|
|
|
|
processor_list = processor_line.strip().split(',')
|
|
for processor in processor_list:
|
|
tmp_list.append(processor.strip())
|
|
break
|
|
|
|
return tmp_list
|
|
|
|
|
|
def get_native_ttys_info(board_info):
|
|
"""
|
|
Get ttySn from board info
|
|
:param board_info: it is a file what contains board information for script to read from
|
|
:return: serial port list
|
|
"""
|
|
ttys_list = []
|
|
ttys_info = get_info(board_info, "<TTYS_INFO>", "</TTYS_INFO>")
|
|
|
|
for ttys_line in ttys_info:
|
|
if not ttys_line:
|
|
break
|
|
|
|
ttys_dev = ttys_line.split()[0].split(':')[1]
|
|
ttysn = ttys_dev.split('/')[-1]
|
|
# currently Service VM OS console can only support legacy serial port
|
|
if ttysn not in list(LEGACY_TTYS.keys()):
|
|
continue
|
|
ttys_list.append(ttys_dev)
|
|
|
|
return ttys_list
|
|
|
|
def get_total_mem():
|
|
"""
|
|
get total memory size from config file which is dumped from native board
|
|
:return: integer number of total memory size, Unit: MByte
|
|
"""
|
|
scale_to_mb = 1
|
|
total_mem_mb = scale_to_mb
|
|
mem_lines = get_info(common.BOARD_INFO_FILE, "<TOTAL_MEM_INFO>", "</TOTAL_MEM_INFO>")
|
|
for mem_line in mem_lines:
|
|
mem_info_list = mem_line.split()
|
|
|
|
if len(mem_info_list) <= 1:
|
|
return total_mem_mb
|
|
|
|
if mem_info_list[1] == "kB":
|
|
scale_to_mb = 1024
|
|
|
|
total_mem_mb = int(mem_info_list[0]) / scale_to_mb
|
|
return total_mem_mb
|
|
|
|
|
|
def get_pci_info(board_info):
|
|
pci_bdf_vpid = {}
|
|
pci_vid_start = False
|
|
pci_vid_end = False
|
|
pci_desc = {}
|
|
pci_start = False
|
|
pci_end = False
|
|
|
|
with open(board_info, 'r') as f:
|
|
while True:
|
|
line = f.readline()
|
|
if not line:
|
|
break
|
|
|
|
s = " "
|
|
if s.join(line.split()[0:2]) == "<PCI_DEVICE>":
|
|
pci_start = True
|
|
pci_end = False
|
|
continue
|
|
|
|
if s.join(line.split()[0:2]) == "</PCI_DEVICE>":
|
|
pci_start = False
|
|
pci_end = True
|
|
continue
|
|
|
|
# all pci device wiht description
|
|
if pci_start and not pci_end:
|
|
if "Region" in line and "Memory at" in line:
|
|
continue
|
|
bdf = line.split()[0]
|
|
pci_desc[bdf] = line
|
|
|
|
if s.join(line.split()[0:2]) == "<PCI_VID_PID>":
|
|
pci_vid_start = True
|
|
pci_vid_end = False
|
|
continue
|
|
|
|
if s.join(line.split()[0:2]) == "</PCI_VID_PID>":
|
|
pci_vid_start = False
|
|
pci_vid_end = True
|
|
continue
|
|
|
|
# all pci device with vid/pid and bdf
|
|
if pci_vid_start and not pci_vid_end:
|
|
bdf_str = line.split()[0]
|
|
vid_pid = line.split()[2]
|
|
pci_bdf_vpid[bdf_str] = vid_pid
|
|
|
|
return (pci_desc, pci_bdf_vpid)
|
|
|
|
def get_p_state_count():
|
|
"""
|
|
Get cpu p-state count
|
|
:return: p-state count
|
|
"""
|
|
px_info = get_info(common.BOARD_INFO_FILE, "<PX_INFO>", "</PX_INFO>")
|
|
if px_info != None:
|
|
for line in px_info:
|
|
if re.search("{.*}", line) == None:
|
|
px_info.remove(line)
|
|
|
|
return len(px_info)
|
|
|
|
def get_p_state_index_from_ratio(ratio):
|
|
"""
|
|
Get the closest p-state index that is lesser than or equel to given ratio
|
|
:return: p-state index; If no px_info found in board file, return 0;
|
|
"""
|
|
closest_index = 0
|
|
px_info = get_info(common.BOARD_INFO_FILE, "<PX_INFO>", "</PX_INFO>")
|
|
if px_info != None:
|
|
for line in px_info:
|
|
if re.search("{.*}", line) == None:
|
|
px_info.remove(line)
|
|
|
|
i = 0
|
|
closest_index = 1
|
|
for line in px_info:
|
|
l = re.search("0x(\w*)UL}", line)
|
|
if l != None:
|
|
state_ratio = int(l.group(1), 16) >> 8
|
|
if state_ratio <= ratio:
|
|
closest_index = i
|
|
break
|
|
i += 1
|
|
|
|
return closest_index
|
|
|
|
HI_MMIO_OFFSET = 0
|
|
|
|
class Bar_Mem:
|
|
def __init__(self):
|
|
self.addr = 0
|
|
self.remapped = False
|
|
|
|
|
|
class Bar_Attr:
|
|
def __init__(self):
|
|
self.name = 0
|
|
self.remappable = True
|
|
self.name_w_i_cnt = 0
|
|
|
|
class Pci_Dev_Bar_Desc:
|
|
def __init__(self):
|
|
self.pci_dev_dic = collections.OrderedDict()
|
|
self.pci_bar_dic = collections.OrderedDict()
|
|
self.shm_bar_dic = collections.OrderedDict()
|
|
|
|
PCI_DEV_BAR_DESC = Pci_Dev_Bar_Desc()
|
|
SUB_NAME_COUNT = collections.OrderedDict()
|
|
|
|
|
|
def get_value_after_str(line, key):
|
|
""" Get the value after cstate string """
|
|
idx = 0
|
|
line_in_list = line.split()
|
|
for idx_key, val in enumerate(line_in_list):
|
|
if val == key:
|
|
idx = idx_key
|
|
break
|
|
|
|
return line_in_list[idx + 1]
|
|
|
|
|
|
def check_bar_remappable(line):
|
|
#TODO: check device BAR remappable per ACPI table
|
|
|
|
return True
|
|
|
|
|
|
def get_size(line):
|
|
|
|
# get size string from format, Region n: Memory at x ... [size=NK]
|
|
size_str = line.split()[-1].strip(']').split('=')[1]
|
|
if 'G' in size_str:
|
|
size = int(size_str.strip('G')) * common.SIZE_G
|
|
elif 'M' in size_str:
|
|
size = int(size_str.strip('M')) * common.SIZE_M
|
|
elif 'K' in size_str:
|
|
size = int(size_str.strip('K')) * common.SIZE_K
|
|
else:
|
|
size = int(size_str)
|
|
|
|
return size
|
|
|
|
# round up the running bar_addr to the size of the incoming bar "line"
|
|
def remap_bar_addr_to_high(bar_addr, line):
|
|
"""Generate vbar address"""
|
|
global HI_MMIO_OFFSET
|
|
size = get_size(line)
|
|
cur_addr = common.round_up(bar_addr, size)
|
|
HI_MMIO_OFFSET = cur_addr + size
|
|
return cur_addr
|
|
|
|
|
|
def parser_pci():
|
|
""" Parse PCI lines """
|
|
global SUB_NAME_COUNT, HI_MMIO_OFFSET
|
|
cur_bdf = 0
|
|
prev_bdf = 0
|
|
tmp_bar_dic = {}
|
|
bar_addr = bar_num = '0'
|
|
cal_sub_pci_name = []
|
|
|
|
pci_lines = get_info(common.BOARD_INFO_FILE, "<PCI_DEVICE>", "</PCI_DEVICE>")
|
|
|
|
for line in pci_lines:
|
|
tmp_bar_mem = Bar_Mem()
|
|
# get pci bar information into board_cfg_lib.PCI_DEV_BAR_DESC
|
|
if "Region" in line and "Memory at" in line:
|
|
#ignore memory region from SR-IOV capabilities
|
|
if "size=" not in line:
|
|
continue
|
|
|
|
try:
|
|
bar_addr = int(get_value_after_str(line, "at"), 16)
|
|
except ValueError:
|
|
continue
|
|
|
|
bar_num = line.split()[1].strip(':')
|
|
if bar_addr >= common.SIZE_4G or bar_addr < common.SIZE_2G:
|
|
if not tmp_bar_attr.remappable:
|
|
continue
|
|
|
|
bar_addr = remap_bar_addr_to_high(HI_MMIO_OFFSET, line)
|
|
tmp_bar_mem.remapped = True
|
|
|
|
tmp_bar_mem.addr = hex(bar_addr)
|
|
tmp_bar_dic[int(bar_num)] = tmp_bar_mem
|
|
else:
|
|
tmp_bar_attr = Bar_Attr()
|
|
prev_bdf = cur_bdf
|
|
pci_bdf = line.split()[0]
|
|
tmp_bar_attr.name = " ".join(line.split(':')[1].split()[1:])
|
|
|
|
# remove '[*]' in pci subname
|
|
if '[' in tmp_bar_attr.name:
|
|
tmp_bar_attr.name = tmp_bar_attr.name.rsplit('[', 1)[0]
|
|
|
|
cal_sub_pci_name.append(tmp_bar_attr.name)
|
|
tmp_bar_attr.remappable = check_bar_remappable(line)
|
|
PCI_DEV_BAR_DESC.pci_dev_dic[pci_bdf] = tmp_bar_attr
|
|
cur_bdf = pci_bdf
|
|
|
|
if not prev_bdf:
|
|
prev_bdf = cur_bdf
|
|
|
|
if tmp_bar_dic and cur_bdf != prev_bdf:
|
|
PCI_DEV_BAR_DESC.pci_bar_dic[prev_bdf] = tmp_bar_dic
|
|
|
|
# clear the tmp_bar_dic before store the next dic
|
|
tmp_bar_dic = {}
|
|
|
|
# output all the pci device list to pci_device.h
|
|
for item in cal_sub_pci_name:
|
|
SUB_NAME_COUNT[item] = SUB_NAME_COUNT.get(item, 0) + 1
|
|
|
|
if tmp_bar_dic:
|
|
PCI_DEV_BAR_DESC.pci_bar_dic[cur_bdf] = tmp_bar_dic
|
|
|
|
|
|
def parse_mem():
|
|
raw_shmem_regions = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "IVSHMEM", "IVSHMEM_REGION")
|
|
|
|
global USED_RAM_RANGE
|
|
for shm_name, shm_bar_dic in PCI_DEV_BAR_DESC.shm_bar_dic.items():
|
|
if 0 in shm_bar_dic.keys() and int(shm_bar_dic[0].addr, 16) in USED_RAM_RANGE.keys():
|
|
del USED_RAM_RANGE[int(shm_bar_dic[0].addr, 16)]
|
|
if 2 in shm_bar_dic.keys() and int(shm_bar_dic[2].addr, 16)-0xC in USED_RAM_RANGE.keys():
|
|
del USED_RAM_RANGE[int(shm_bar_dic[2].addr, 16)-0xC]
|
|
|
|
idx = 0
|
|
for shm in raw_shmem_regions:
|
|
if shm is None or shm.strip() == '':
|
|
continue
|
|
shm_splited = shm.split(',')
|
|
name = shm_splited[0].strip()
|
|
size = shm_splited[1].strip()
|
|
|
|
try:
|
|
int_size = int(size) * 0x100000
|
|
except:
|
|
int_size = 0
|
|
ram_range = get_ram_range()
|
|
tmp_bar_dict = {}
|
|
hv_start_offset = 0x80000000
|
|
ret_start_addr = find_avl_memory(ram_range, str(0x200100), hv_start_offset)
|
|
bar_mem_0 = Bar_Mem()
|
|
bar_mem_0.addr = hex(common.round_up(int(ret_start_addr, 16), 0x200000))
|
|
USED_RAM_RANGE[int(bar_mem_0.addr, 16)] = 0x100
|
|
tmp_bar_dict[0] = bar_mem_0
|
|
ram_range = get_ram_range()
|
|
hv_start_offset2 = 0x100000000
|
|
ret_start_addr2 = find_avl_memory(ram_range, str(int_size + 0x200000), hv_start_offset2)
|
|
bar_mem_2 = Bar_Mem()
|
|
bar_mem_2.addr = hex(common.round_up(int(ret_start_addr2, 16), 0x200000) + 0xC)
|
|
USED_RAM_RANGE[common.round_up(int(ret_start_addr2, 16), 0x20000)] = int_size
|
|
tmp_bar_dict[2] = bar_mem_2
|
|
PCI_DEV_BAR_DESC.shm_bar_dic[str(idx)+'_'+name] = tmp_bar_dict
|
|
idx += 1
|
|
|
|
|
|
def is_rdt_supported():
|
|
"""
|
|
Returns True if platform supports RDT else False
|
|
"""
|
|
(rdt_resources, rdt_res_clos_max, _) = clos_info_parser(common.BOARD_INFO_FILE)
|
|
if len(rdt_resources) == 0 or len(rdt_res_clos_max) == 0:
|
|
return False
|
|
else:
|
|
return True
|
|
|
|
|
|
def is_rdt_enabled():
|
|
"""
|
|
Returns True if RDT enabled else False
|
|
"""
|
|
rdt_enabled = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "RDT", "RDT_ENABLED")
|
|
if is_rdt_supported() and rdt_enabled == 'y':
|
|
return True
|
|
return False
|
|
|
|
|
|
def is_cdp_enabled():
|
|
"""
|
|
Returns True if platform supports RDT/CDP else False
|
|
"""
|
|
rdt_enabled = is_rdt_enabled()
|
|
cdp_enabled = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "RDT", "CDP_ENABLED")
|
|
if rdt_enabled and cdp_enabled == 'y':
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def get_rdt_select_opt():
|
|
|
|
support_sel = ['n']
|
|
if is_rdt_supported():
|
|
support_sel.append('y')
|
|
return support_sel
|
|
|
|
|
|
def get_common_clos_max():
|
|
|
|
common_clos_max = 0
|
|
(res_info, rdt_res_clos_max, clos_max_mask_list) = clos_info_parser(common.BOARD_INFO_FILE)
|
|
if is_rdt_enabled() and not is_cdp_enabled():
|
|
common_clos_max = min(rdt_res_clos_max)
|
|
|
|
if is_cdp_enabled():
|
|
tmp_clos_max_list = []
|
|
for res, clos_max in zip(res_info, rdt_res_clos_max):
|
|
if res == 'MBA':
|
|
tmp_clos_max_list.append(clos_max)
|
|
else:
|
|
tmp_clos_max_list.append(clos_max//2)
|
|
common_clos_max = min(tmp_clos_max_list)
|
|
|
|
return common_clos_max
|
|
|
|
|
|
def get_sub_pci_name(i_cnt, bar_attr):
|
|
tmp_sub_name = ''
|
|
# if there is only one host bridge, then will discard the index of suffix
|
|
if i_cnt == 0 and bar_attr.name.upper() == "HOST BRIDGE":
|
|
tmp_sub_name = "_".join(bar_attr.name.split()).upper()
|
|
else:
|
|
if '-' in bar_attr.name:
|
|
tmp_sub_name = common.undline_name(bar_attr.name) + "_" + str(i_cnt)
|
|
else:
|
|
tmp_sub_name = "_".join(bar_attr.name.split()).upper() + "_" + str(i_cnt)
|
|
|
|
return tmp_sub_name
|
|
|
|
def get_known_caps_pci_devs():
|
|
known_caps_pci_devs = {}
|
|
vpid_lines = get_info(common.BOARD_INFO_FILE, "<PCI_VID_PID>", "</PCI_VID_PID>")
|
|
for dev,known_dev in KNOWN_CAPS_PCI_DEVS_DB.items():
|
|
if dev not in known_caps_pci_devs:
|
|
known_caps_pci_devs[dev] = []
|
|
for k_dev in known_dev:
|
|
for vpid_line in vpid_lines:
|
|
if k_dev in vpid_line:
|
|
bdf = vpid_line.split()[0]
|
|
known_caps_pci_devs[dev].append(bdf)
|
|
break
|
|
|
|
return known_caps_pci_devs
|
|
|
|
|
|
def is_tpm_passthru():
|
|
|
|
tpm_passthru = False
|
|
(_, board) = common.get_board_name()
|
|
tpm2_passthru_enabled = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "mmio_resources", "TPM2")
|
|
if board in TPM_PASSTHRU_BOARD and tpm2_passthru_enabled and 'y' in tpm2_passthru_enabled.values():
|
|
tpm_passthru = True
|
|
|
|
return tpm_passthru
|
|
|
|
|
|
def find_avl_memory(ram_range, hpa_size, hv_start_offset):
|
|
"""
|
|
This is get hv address from System RAM as host physical size
|
|
:param ram_range: System RAM mapping
|
|
:param hpa_size: fixed host physical size
|
|
:param hv_start_offset: base address of HV RAM start
|
|
:return: start host physical address
|
|
"""
|
|
ret_start_addr = 0
|
|
tmp_order_key = 0
|
|
int_hpa_size = int(hpa_size, 10)
|
|
|
|
tmp_order_key = sorted(ram_range)
|
|
for start_addr in tmp_order_key:
|
|
mem_range = ram_range[start_addr]
|
|
if start_addr <= hv_start_offset and hv_start_offset + int_hpa_size <= start_addr + mem_range:
|
|
ret_start_addr = hv_start_offset
|
|
break
|
|
elif start_addr >= hv_start_offset and mem_range >= int_hpa_size:
|
|
ret_start_addr = start_addr
|
|
break
|
|
|
|
return hex(ret_start_addr)
|
|
|
|
|
|
def get_ram_range():
|
|
""" Get System RAM range mapping """
|
|
# read system ram from board_info.xml
|
|
ram_range = {}
|
|
|
|
io_mem_lines = get_info(
|
|
common.BOARD_INFO_FILE, "<IOMEM_INFO>", "</IOMEM_INFO>")
|
|
|
|
for line in io_mem_lines:
|
|
if 'System RAM' not in line:
|
|
continue
|
|
start_addr = int(line.split('-')[0], 16)
|
|
end_addr = int(line.split('-')[1].split(':')[0], 16)
|
|
mem_range = end_addr - start_addr
|
|
ram_range[start_addr] = mem_range
|
|
|
|
global USED_RAM_RANGE
|
|
tmp_order_key_used = sorted(USED_RAM_RANGE)
|
|
for start_addr_used in tmp_order_key_used:
|
|
mem_range_used = USED_RAM_RANGE[start_addr_used]
|
|
tmp_order_key = sorted(ram_range)
|
|
for start_addr in tmp_order_key:
|
|
mem_range = ram_range[start_addr]
|
|
if start_addr < start_addr_used and start_addr_used + mem_range_used < start_addr + mem_range:
|
|
ram_range[start_addr] = start_addr_used - start_addr
|
|
ram_range[start_addr_used+mem_range_used] = start_addr + mem_range - start_addr_used - mem_range_used
|
|
break
|
|
elif start_addr == start_addr_used and start_addr_used + mem_range_used < start_addr + mem_range:
|
|
del ram_range[start_addr]
|
|
ram_range[start_addr_used + mem_range_used] = start_addr + mem_range - start_addr_used - mem_range_used
|
|
break
|
|
elif start_addr < start_addr_used and start_addr_used + mem_range_used == start_addr + mem_range:
|
|
ram_range[start_addr] = start_addr_used - start_addr
|
|
break
|
|
elif start_addr == start_addr_used and start_addr_used + mem_range_used == start_addr + mem_range:
|
|
del ram_range[start_addr]
|
|
break
|
|
else:
|
|
continue
|
|
|
|
return ram_range
|
|
|
|
|
|
def is_p2sb_passthru_possible():
|
|
|
|
p2sb_passthru = False
|
|
(_, board) = common.get_board_name()
|
|
if board in P2SB_PASSTHRU_BOARD:
|
|
p2sb_passthru = True
|
|
|
|
return p2sb_passthru
|
|
|
|
|
|
def is_matched_board(boardlist):
|
|
|
|
(_, board) = common.get_board_name()
|
|
|
|
return board in boardlist
|
|
|
|
|
|
def find_p2sb_bar_addr():
|
|
if not is_matched_board(('ehl-crb-b')):
|
|
common.print_red('find_p2sb_bar_addr() can only be called for board ehl-crb-b', err=True)
|
|
sys.exit(1)
|
|
|
|
iomem_lines = get_info(common.BOARD_INFO_FILE, "<IOMEM_INFO>", "</IOMEM_INFO>")
|
|
|
|
for line in iomem_lines:
|
|
if 'INTC1020:' in line:
|
|
start_addr = int(line.split('-')[0], 16) & 0xFF000000
|
|
return start_addr
|
|
|
|
common.print_red('p2sb device is not found in board file %s!\n' % common.BOARD_INFO_FILE, err=True)
|
|
sys.exit(1)
|