mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-25 10:43:46 +00:00
acrn-config: Reorg config tool folder
Remove vm_configs folder and move all the XML files and generic code example into config_tools/data Tracked-On: #5644 Signed-off-by: Xie, nanlin <nanlin.xie@intel.com>
This commit is contained in:
6
misc/config_tools/board_config/README
Normal file
6
misc/config_tools/board_config/README
Normal file
@@ -0,0 +1,6 @@
|
||||
Please run board_cfg_gen.py to generate board related configuration files.
|
||||
|
||||
usage: python3 board_cfg_gen.py [h] --board <board_info_file> --scenario <scenario_info_file>
|
||||
positional arguments:
|
||||
board_info_file : file name of the board info XML
|
||||
scenario_info_file : file name of the scenario info XML
|
242
misc/config_tools/board_config/acpi_platform_h.py
Normal file
242
misc/config_tools/board_config/acpi_platform_h.py
Normal file
@@ -0,0 +1,242 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
import board_cfg_lib
|
||||
import common
|
||||
|
||||
PLATFORM_HEADER = r"""/* DO NOT MODIFY THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_ACPI_INFO_H
|
||||
#define PLATFORM_ACPI_INFO_H
|
||||
"""
|
||||
|
||||
PLATFORM_END_HEADER = "#endif /* PLATFORM_ACPI_INFO_H */"
|
||||
|
||||
|
||||
class OverridAccessSize():
|
||||
""" The Pm access size which are needed to redefine """
|
||||
def __init__(self):
|
||||
self.pm1a_cnt_ac_sz = True
|
||||
self.pm1b_cnt_ac_sz = True
|
||||
self.pm1b_evt_ac_sz = True
|
||||
|
||||
def style_check_1(self):
|
||||
""" Style check if have public method """
|
||||
self.pm1a_cnt_ac_sz = True
|
||||
|
||||
def style_check_2(self):
|
||||
""" Style check if have public method """
|
||||
self.pm1a_cnt_ac_sz = True
|
||||
|
||||
|
||||
def multi_parser(line, s_line, pm_ac_sz, config):
|
||||
"""
|
||||
Multi parse the line
|
||||
:param line: it is a line read from default_acpi_info.h
|
||||
:param s_line: it is a line read from board information file
|
||||
:param pm_ac_sz: it is a class for access size which would be override
|
||||
:param config: it is a file pointer to write acpi information
|
||||
"""
|
||||
addr = ['PM1A_EVT_ADDRESS', 'PM1B_EVT_ADDRESS', 'PM1A_CNT_ADDRESS', 'PM1B_CNT_ADDRESS']
|
||||
space_id = ['PM1A_EVT_SPACE_ID', 'PM1B_EVT_SPACE_ID', 'PM1A_CNT_SPACE_ID', 'PM1B_CNT_SPACE_ID']
|
||||
|
||||
if line.split()[1] in space_id and line.split()[1] == s_line.split()[1]:
|
||||
if line.split()[2] != s_line.split()[2]:
|
||||
print("#undef {}".format(s_line.split()[1]), file=config)
|
||||
print("{}".format(s_line.strip()), file=config)
|
||||
return
|
||||
|
||||
if line.split()[1] in addr and line.split()[1] == s_line.split()[1]:
|
||||
if int(line.split()[2].strip('UL'), 16) != \
|
||||
int(s_line.split()[2].strip('UL'), 16) and \
|
||||
int(s_line.split()[2].strip('UL'), 16) != 0:
|
||||
print("#undef {}".format(s_line.split()[1]), file=config)
|
||||
print("{}".format(s_line.strip()), file=config)
|
||||
else:
|
||||
if "PM1B_EVT" in line.split()[1]:
|
||||
pm_ac_sz.pm1b_evt_ac_sz = False
|
||||
if "PM1B_CNT" in line.split()[1]:
|
||||
pm_ac_sz.pm1b_cnt_ac_sz = False
|
||||
|
||||
return
|
||||
|
||||
if line.split()[1] == s_line.split()[1]:
|
||||
if "PM1B_EVT" in line.split()[1] and not pm_ac_sz.pm1b_evt_ac_sz:
|
||||
return
|
||||
|
||||
if "PM1B_CNT" in line.split()[1] and not pm_ac_sz.pm1b_cnt_ac_sz:
|
||||
return
|
||||
|
||||
if "PM1A_CNT" in line.split()[1] and not pm_ac_sz.pm1a_cnt_ac_sz:
|
||||
return
|
||||
|
||||
if int(line.split()[2].strip('U'), 16) != int(s_line.split()[2].strip('U'), 16):
|
||||
print("#undef {}".format(s_line.split()[1]), file=config)
|
||||
print("{}".format(s_line.strip()), file=config)
|
||||
|
||||
|
||||
def multi_info_parser(config, default_platform, msg_s, msg_e):
|
||||
"""
|
||||
Parse multi information
|
||||
:param config: it is a file pointer to write acpi information
|
||||
:param default_platform: it is the default_acpi_info.h in acrn-hypervisor
|
||||
: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
|
||||
"""
|
||||
write_direct = ['PM1A_EVT_ACCESS_SIZE', 'PM1A_EVT_ADDRESS', 'PM1A_CNT_ADDRESS']
|
||||
|
||||
pm_ac_sz = OverridAccessSize()
|
||||
multi_lines = board_cfg_lib.get_info(common.BOARD_INFO_FILE, msg_s, msg_e)
|
||||
|
||||
msg_name = msg_s.split('_')[0].strip('<')
|
||||
|
||||
# Set defaults for PM1A registers if not present in target xml file
|
||||
if not multi_lines and msg_name in ("PM1A"):
|
||||
print("#define PM1A_EVT_ACCESS_SIZE\t0U", file=config)
|
||||
print("#define PM1A_EVT_ADDRESS\t0UL", file=config)
|
||||
print("#define PM1A_CNT_ADDRESS\t0UL", file=config)
|
||||
return
|
||||
|
||||
# S3/S5 not supported by BIOS
|
||||
if not multi_lines and msg_name in ("S3", "S5"):
|
||||
print("/* {} is not supported by BIOS */".format(msg_name), file=config)
|
||||
return
|
||||
|
||||
for s_line in multi_lines:
|
||||
# parse the commend line
|
||||
if '/*' in s_line:
|
||||
print("{}".format(s_line), file=config)
|
||||
continue
|
||||
|
||||
if s_line.split()[1] in write_direct:
|
||||
if "PM1A_CNT" in s_line.split()[1] and int(s_line.split()[2].strip('UL'), 16) == 0:
|
||||
pm_ac_sz.pm1a_cnt_ac_sz = False
|
||||
|
||||
print("{}".format(s_line.strip()), file=config)
|
||||
continue
|
||||
|
||||
with open(default_platform, 'r') as default:
|
||||
while True:
|
||||
line = default.readline()
|
||||
|
||||
if not line:
|
||||
break
|
||||
|
||||
if len(line.split()) < 2:
|
||||
continue
|
||||
|
||||
multi_parser(line, s_line, pm_ac_sz, config)
|
||||
|
||||
|
||||
def write_direct_info_parser(config, msg_s, msg_e):
|
||||
"""
|
||||
Direct to write
|
||||
:param config: it is a file pointer to write acpi information
|
||||
: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
|
||||
"""
|
||||
vector_lines = board_cfg_lib.get_info(common.BOARD_INFO_FILE, msg_s, msg_e)
|
||||
msg_name = msg_s.split('_')[0].strip('<')
|
||||
|
||||
# Set defaults if not present in target xml file
|
||||
if not vector_lines and msg_name in ("WAKE"):
|
||||
print("\n#define WAKE_VECTOR_32\t\t0UL", file=config)
|
||||
print("#define WAKE_VECTOR_64\t\t0UL", file=config)
|
||||
return
|
||||
|
||||
if not vector_lines and msg_name in ("RESET"):
|
||||
print("\n#define RESET_REGISTER_ADDRESS\t0UL", file=config)
|
||||
print("#define RESET_REGISTER_VALUE\t0UL", file=config)
|
||||
print("#define RESET_REGISTER_SPACE_ID\t0UL", file=config)
|
||||
return
|
||||
|
||||
if not vector_lines and msg_name in ("MMCFG"):
|
||||
print("\n#define DEFAULT_PCI_MMCFG_BASE\t0UL", file=config)
|
||||
return
|
||||
|
||||
if msg_name in ("IOMEM"):
|
||||
if vector_lines:
|
||||
for vector in vector_lines:
|
||||
if "MMCONFIG" in vector:
|
||||
try:
|
||||
bus_list = vector.split("bus")[1].strip().split("-")
|
||||
start_bus_number = int(bus_list[0].strip(), 16)
|
||||
end_bus_number = int(bus_list[1].strip("]"), 16)
|
||||
print("/* PCI mmcfg bus number of MCFG */", file=config)
|
||||
print("#define DEFAULT_PCI_MMCFG_START_BUS \t 0x{:X}U".format(start_bus_number), file=config)
|
||||
print("#define DEFAULT_PCI_MMCFG_END_BUS \t 0x{:X}U\n".format(end_bus_number), file=config)
|
||||
print("", file=config)
|
||||
return
|
||||
except:
|
||||
pass
|
||||
|
||||
print("/* PCI mmcfg bus number of MCFG */", file=config)
|
||||
print("#define DEFAULT_PCI_MMCFG_START_BUS\t0U", file=config)
|
||||
print("#define DEFAULT_PCI_MMCFG_END_BUS\t0U", file=config)
|
||||
print("", file=config)
|
||||
return
|
||||
|
||||
for vector in vector_lines:
|
||||
print("{}".format(vector.strip()), file=config)
|
||||
|
||||
print("", file=config)
|
||||
|
||||
|
||||
def drhd_info_parser(config):
|
||||
"""
|
||||
Parse DRHD information
|
||||
:param config: it is a file pointer to write acpi information
|
||||
"""
|
||||
prev_num = 0
|
||||
|
||||
drhd_lines = board_cfg_lib.get_info(
|
||||
common.BOARD_INFO_FILE, "<DRHD_INFO>", "</DRHD_INFO>")
|
||||
|
||||
# write DRHD
|
||||
print("/* DRHD of DMAR */", file=config)
|
||||
|
||||
if not drhd_lines:
|
||||
print("\n#define DRHD_COUNT\t\t8U", file=config)
|
||||
return
|
||||
|
||||
for drhd in drhd_lines:
|
||||
print(drhd.strip(), file=config)
|
||||
|
||||
|
||||
def platform_info_parser(config, default_platform):
|
||||
"""
|
||||
Parse ACPI information
|
||||
:param config: it is a file pointer to write acpi information
|
||||
:param default_platform: it is the default_acpi_info.h in acrn-hypervisor
|
||||
"""
|
||||
print("\n/* pm sstate data */", file=config)
|
||||
multi_info_parser(config, default_platform, "<PM_INFO>", "</PM_INFO>")
|
||||
multi_info_parser(config, default_platform, "<S3_INFO>", "</S3_INFO>")
|
||||
multi_info_parser(config, default_platform, "<S5_INFO>", "</S5_INFO>")
|
||||
print("", file=config)
|
||||
|
||||
write_direct_info_parser(config, "<WAKE_VECTOR_INFO>", "</WAKE_VECTOR_INFO>")
|
||||
write_direct_info_parser(config, "<RESET_REGISTER_INFO>", "</RESET_REGISTER_INFO>")
|
||||
drhd_info_parser(config)
|
||||
write_direct_info_parser(config, "<MMCFG_BASE_INFO>", "</MMCFG_BASE_INFO>")
|
||||
write_direct_info_parser(config, "<IOMEM_INFO>", "</IOMEM_INFO>")
|
||||
|
||||
|
||||
def generate_file(config, default_platform):
|
||||
"""
|
||||
write board_name_acpi_info.h
|
||||
:param config: it is a file pointer to write acpi information
|
||||
:param default_platform: it is the default_acpi_info.h in acrn-hypervisor
|
||||
"""
|
||||
print("{}".format(board_cfg_lib.HEADER_LICENSE), file=config)
|
||||
|
||||
print("{}".format(PLATFORM_HEADER), file=config)
|
||||
|
||||
board_cfg_lib.handle_bios_info(config)
|
||||
# parse for the platform info
|
||||
platform_info_parser(config, default_platform)
|
||||
|
||||
print("{}".format(PLATFORM_END_HEADER), file=config)
|
317
misc/config_tools/board_config/board_c.py
Normal file
317
misc/config_tools/board_config/board_c.py
Normal file
@@ -0,0 +1,317 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
import sys
|
||||
import enum
|
||||
import subprocess
|
||||
import board_cfg_lib
|
||||
import common
|
||||
|
||||
class RDT(enum.Enum):
|
||||
L2 = 0
|
||||
L3 = 1
|
||||
MBA = 2
|
||||
|
||||
INCLUDE_HEADER = """
|
||||
#include <board.h>
|
||||
#include <vtd.h>
|
||||
#include <msr.h>
|
||||
#include <pci.h>
|
||||
#include <misc_cfg.h>
|
||||
"""
|
||||
|
||||
MSR_IA32_L2_MASK_BASE = 0x00000D10
|
||||
MSR_IA32_L2_MASK_END = 0x00000D4F
|
||||
MSR_IA32_L3_MASK_BASE = 0x00000C90
|
||||
MSR_IA32_L3_MASK_END = 0x00000D0F
|
||||
|
||||
|
||||
def gen_dmar_structure(config):
|
||||
"""Generate dmar structure information"""
|
||||
|
||||
dmar_info_lines = board_cfg_lib.get_info(common.BOARD_INFO_FILE, "<DRHD_INFO>", "</DRHD_INFO>")
|
||||
drhd_cnt = 0
|
||||
drhd_dev_scope_cnt = []
|
||||
dev_scope_type = []
|
||||
|
||||
if not dmar_info_lines:
|
||||
print("\n#ifndef CONFIG_ACPI_PARSE_ENABLED", file=config)
|
||||
print("#error \"DMAR info is not available, please set ACPI_PARSE_ENABLED to y in Kconfig. \\", file=config)
|
||||
print("\tOr use acrn-config tool to generate platform DMAR info.\"", file=config)
|
||||
print("#endif\n", file=config)
|
||||
|
||||
print("struct dmar_info plat_dmar_info;\n", file=config)
|
||||
return
|
||||
|
||||
# parse to get DRHD count and dev scope count
|
||||
for dmar_line in dmar_info_lines:
|
||||
if "DRHD_COUNT" in dmar_line and not drhd_cnt:
|
||||
drhd_cnt = int(dmar_line.split()[2].strip('U'))
|
||||
|
||||
for i_cnt in range(drhd_cnt):
|
||||
for dmar_line in dmar_info_lines:
|
||||
dev_scope_cnt_str = "DRHD{}_DEV_CNT".format(i_cnt)
|
||||
|
||||
if dev_scope_cnt_str in dmar_line:
|
||||
tmp_dev_scope_cnt = int(dmar_line.split()[2].strip('U'), 16)
|
||||
drhd_dev_scope_cnt.append(tmp_dev_scope_cnt)
|
||||
|
||||
# gen dmar structure information
|
||||
for i_drhd_cnt in range(drhd_cnt):
|
||||
dev_cnt = drhd_dev_scope_cnt[i_drhd_cnt]
|
||||
print("static struct dmar_dev_scope drhd{}_dev_scope[DRHD{}_DEV_CNT] = {{".format(
|
||||
i_drhd_cnt, i_drhd_cnt), file=config)
|
||||
for i_dev_cnt in range(dev_cnt):
|
||||
print("\t{", file=config)
|
||||
print("\t\t.type = DRHD{}_DEVSCOPE{}_TYPE,".format(i_drhd_cnt, i_dev_cnt), file=config)
|
||||
print("\t\t.id = DRHD{}_DEVSCOPE{}_ID,".format(i_drhd_cnt, i_dev_cnt), file=config)
|
||||
print("\t\t.bus = DRHD{}_DEVSCOPE{}_BUS,".format(i_drhd_cnt, i_dev_cnt), file=config)
|
||||
print("\t\t.devfun = DRHD{}_DEVSCOPE{}_PATH,".format(i_drhd_cnt, i_dev_cnt), file=config)
|
||||
print("\t},", file=config)
|
||||
|
||||
print("};", file=config)
|
||||
print("", file=config)
|
||||
|
||||
print("static struct dmar_drhd drhd_info_array[DRHD_COUNT] = {", file=config)
|
||||
for i_drhd_cnt in range(drhd_cnt):
|
||||
print("\t{", file=config)
|
||||
print("\t\t.dev_cnt = DRHD{}_DEV_CNT,".format(i_drhd_cnt), file=config)
|
||||
print("\t\t.segment = DRHD{}_SEGMENT,".format(i_drhd_cnt), file=config)
|
||||
print("\t\t.flags = DRHD{}_FLAGS,".format(i_drhd_cnt), file=config)
|
||||
print("\t\t.reg_base_addr = DRHD{}_REG_BASE,".format(i_drhd_cnt), file=config)
|
||||
print("\t\t.ignore = DRHD{}_IGNORE,".format(i_drhd_cnt), file=config)
|
||||
print("\t\t.devices = drhd{}_dev_scope".format(i_drhd_cnt), file=config)
|
||||
print("\t},", file=config)
|
||||
|
||||
print("};", file=config)
|
||||
print("", file=config)
|
||||
print("struct dmar_info plat_dmar_info = {", file=config)
|
||||
print("\t.drhd_count = DRHD_COUNT,", file=config)
|
||||
print("\t.drhd_units = drhd_info_array,", file=config)
|
||||
print("};", file=config)
|
||||
|
||||
|
||||
def populate_clos_mask_msr(rdt_res, cat_mask_list, config):
|
||||
"""
|
||||
Populate the clos bitmask and msr index for a given RDT resource
|
||||
:param rdt_res: it is a string representing the RDT resource
|
||||
:param cat_mask_list: cache mask list corresponding to each CLOS
|
||||
:param config: it is a file pointer of board information for writing to
|
||||
"""
|
||||
idx = 0
|
||||
for cat_mask in cat_mask_list:
|
||||
print("\t{", file=config)
|
||||
print("\t\t.value.clos_mask = CLOS_MASK_{},".format(idx), file=config)
|
||||
print("\t\t.msr_index = MSR_IA32_{0}_MASK_BASE + {1},".format(
|
||||
rdt_res, idx), file=config)
|
||||
print("\t},", file=config)
|
||||
idx += 1
|
||||
|
||||
def populate_mba_delay_mask(rdt_res, mba_delay_list, config):
|
||||
"""
|
||||
Populate the mba delay mask and msr index for memory resource
|
||||
:param rdt_res: it is a string representing the RDT resource
|
||||
:param mba_delay_list: mba delay value list corresponding to each CLOS
|
||||
:param config: it is a file pointer of board information for writing to
|
||||
"""
|
||||
idx = 0
|
||||
for mba_delay_mask in mba_delay_list:
|
||||
print("\t{", file=config)
|
||||
print("\t\t.value.mba_delay = MBA_MASK_{},".format(idx), file=config)
|
||||
print("\t\t.msr_index = MSR_IA32_{0}_MASK_BASE + {1},".format(
|
||||
rdt_res, idx), file=config)
|
||||
print("\t},", file=config)
|
||||
idx += 1
|
||||
|
||||
|
||||
def gen_rdt_res(config):
|
||||
"""
|
||||
Get RDT resource (L2, L3, MBA) information
|
||||
:param config: it is a file pointer of board information for writing to
|
||||
"""
|
||||
err_dic = {}
|
||||
rdt_res_str =""
|
||||
res_present = [0, 0, 0]
|
||||
(rdt_resources, rdt_res_clos_max, _) = board_cfg_lib.clos_info_parser(common.BOARD_INFO_FILE)
|
||||
common_clos_max = board_cfg_lib.get_common_clos_max()
|
||||
|
||||
cat_mask_list = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "RDT", "CLOS_MASK")
|
||||
mba_delay_list = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "RDT", "MBA_DELAY")
|
||||
|
||||
if common_clos_max > MSR_IA32_L2_MASK_END - MSR_IA32_L2_MASK_BASE or\
|
||||
common_clos_max > MSR_IA32_L3_MASK_END - MSR_IA32_L3_MASK_BASE:
|
||||
err_dic["board config: generate board.c failed"] = "CLOS MAX should be less than reserved adress region length of L2/L3 cache"
|
||||
return err_dic
|
||||
|
||||
print("\n#ifdef CONFIG_RDT_ENABLED", file=config)
|
||||
if len(rdt_resources) == 0 or common_clos_max == 0:
|
||||
print("struct platform_clos_info platform_{0}_clos_array[MAX_CACHE_CLOS_NUM_ENTRIES];".format("l2"), file=config)
|
||||
print("struct platform_clos_info platform_{0}_clos_array[MAX_CACHE_CLOS_NUM_ENTRIES];".format("l3"), file=config)
|
||||
print("struct platform_clos_info platform_{0}_clos_array[MAX_MBA_CLOS_NUM_ENTRIES];".format("mba"), file=config)
|
||||
else:
|
||||
for idx, rdt_res in enumerate(rdt_resources):
|
||||
if rdt_res == "L2":
|
||||
rdt_res_str = "l2"
|
||||
print("struct platform_clos_info platform_{0}_clos_array[{1}] = {{".format(rdt_res_str,
|
||||
"MAX_CACHE_CLOS_NUM_ENTRIES"), file=config)
|
||||
populate_clos_mask_msr(rdt_res, cat_mask_list, config)
|
||||
print("};\n", file=config)
|
||||
res_present[RDT.L2.value] = 1
|
||||
elif rdt_res == "L3":
|
||||
rdt_res_str = "l3"
|
||||
print("struct platform_clos_info platform_{0}_clos_array[{1}] = {{".format(rdt_res_str,
|
||||
"MAX_CACHE_CLOS_NUM_ENTRIES"), file=config)
|
||||
populate_clos_mask_msr(rdt_res, cat_mask_list, config)
|
||||
print("};\n", file=config)
|
||||
res_present[RDT.L3.value] = 1
|
||||
elif rdt_res == "MBA":
|
||||
rdt_res_str = "mba"
|
||||
print("struct platform_clos_info platform_{0}_clos_array[{1}] = {{".format(rdt_res_str,
|
||||
"MAX_MBA_CLOS_NUM_ENTRIES"), file=config)
|
||||
err_dic = populate_mba_delay_mask(rdt_res, mba_delay_list, config)
|
||||
print("};\n", file=config)
|
||||
res_present[RDT.MBA.value] = 1
|
||||
else:
|
||||
err_dic['board config: generate board.c failed'] = "The input of {} was corrupted!".format(common.BOARD_INFO_FILE)
|
||||
return err_dic
|
||||
|
||||
if res_present[RDT.L2.value] == 0:
|
||||
print("struct platform_clos_info platform_{0}_clos_array[{1}];".format("l2", "MAX_CACHE_CLOS_NUM_ENTRIES"), file=config)
|
||||
if res_present[RDT.L3.value] == 0:
|
||||
print("struct platform_clos_info platform_{0}_clos_array[{1}];".format("l3", "MAX_CACHE_CLOS_NUM_ENTRIES"), file=config)
|
||||
if res_present[RDT.MBA.value] == 0:
|
||||
print("struct platform_clos_info platform_{0}_clos_array[{1}];".format("mba", "MAX_MBA_CLOS_NUM_ENTRIES"), file=config)
|
||||
|
||||
print("#endif", file=config)
|
||||
|
||||
print("", file=config)
|
||||
return err_dic
|
||||
|
||||
|
||||
def gen_single_data(data_lines, domain_str, config):
|
||||
line_i = 0
|
||||
data_statues = True
|
||||
data_len = len(data_lines)
|
||||
|
||||
if data_len == 0:
|
||||
return
|
||||
|
||||
for data_l in data_lines:
|
||||
if line_i == 0:
|
||||
if "not available" in data_l:
|
||||
print(data_l.strip(), file=config)
|
||||
print("static const struct cpu_{}x_data board_cpu_{}x[0];".format(domain_str, domain_str), file=config)
|
||||
print("", file=config)
|
||||
data_statues = False
|
||||
break
|
||||
else:
|
||||
print("static const struct cpu_{}x_data board_cpu_{}x[{}] = {{".format(domain_str, domain_str, data_len), file=config)
|
||||
print("\t{0}".format(data_l.strip()), file=config)
|
||||
line_i += 1
|
||||
if data_statues:
|
||||
print("};\n", file=config)
|
||||
|
||||
|
||||
def gen_px_cx(config):
|
||||
"""
|
||||
Get Px/Cx and store them to board.c
|
||||
:param config: it is a file pointer of board information for writing to
|
||||
"""
|
||||
cpu_brand_lines = board_cfg_lib.get_info(
|
||||
common.BOARD_INFO_FILE, "<CPU_BRAND>", "</CPU_BRAND>")
|
||||
cx_lines = board_cfg_lib.get_info(common.BOARD_INFO_FILE, "<CX_INFO>", "</CX_INFO>")
|
||||
px_lines = board_cfg_lib.get_info(common.BOARD_INFO_FILE, "<PX_INFO>", "</PX_INFO>")
|
||||
|
||||
gen_single_data(cx_lines, 'c', config)
|
||||
gen_single_data(px_lines, 'p', config)
|
||||
|
||||
if not cpu_brand_lines:
|
||||
print("\nconst struct cpu_state_table board_cpu_state_tbl;\n", file=config)
|
||||
return
|
||||
|
||||
for brand_line in cpu_brand_lines:
|
||||
cpu_brand = brand_line
|
||||
|
||||
print("const struct cpu_state_table board_cpu_state_tbl = {", file=config)
|
||||
print("\t{0},".format(cpu_brand.strip()), file=config)
|
||||
print("\t{(uint8_t)ARRAY_SIZE(board_cpu_px), board_cpu_px,", file=config)
|
||||
print("\t(uint8_t)ARRAY_SIZE(board_cpu_cx), board_cpu_cx}", file=config)
|
||||
print("};", file=config)
|
||||
|
||||
|
||||
def gen_pci_hide(config):
|
||||
"""Generate hide pci information for this platform"""
|
||||
if board_cfg_lib.BOARD_NAME in list(board_cfg_lib.KNOWN_HIDDEN_PDEVS_BOARD_DB.keys()) and board_cfg_lib.KNOWN_HIDDEN_PDEVS_BOARD_DB[board_cfg_lib.BOARD_NAME] != 0:
|
||||
hidden_pdev_list = board_cfg_lib.KNOWN_HIDDEN_PDEVS_BOARD_DB[board_cfg_lib.BOARD_NAME]
|
||||
hidden_pdev_num = len(hidden_pdev_list)
|
||||
print("const union pci_bdf plat_hidden_pdevs[MAX_HIDDEN_PDEVS_NUM] = {", file=config)
|
||||
for hidden_pdev_i in range(hidden_pdev_num):
|
||||
bus = hex(int(hidden_pdev_list[hidden_pdev_i].split(':')[0], 16))
|
||||
dev = hex(int(hidden_pdev_list[hidden_pdev_i].split(':')[1], 16))
|
||||
fun = hex(int(hidden_pdev_list[hidden_pdev_i].split(':')[2], 16))
|
||||
print("\t{", file=config)
|
||||
print("\t\t.bits.b = {}U,".format(bus), file=config)
|
||||
print("\t\t.bits.d = {}U,".format(dev), file=config)
|
||||
print("\t\t.bits.f = {}U,".format(fun), file=config)
|
||||
print("\t},", file=config)
|
||||
print("};", file=config)
|
||||
else:
|
||||
print("const union pci_bdf plat_hidden_pdevs[MAX_HIDDEN_PDEVS_NUM];", file=config)
|
||||
|
||||
|
||||
def gen_known_caps_pci_devs(config):
|
||||
"""Generate information for known capabilities of pci devices"""
|
||||
known_caps_pci_devs = board_cfg_lib.get_known_caps_pci_devs()
|
||||
for dev,bdf_list in known_caps_pci_devs.items():
|
||||
if dev == "VMSIX":
|
||||
print("", file=config)
|
||||
bdf_list_len = len(bdf_list)
|
||||
if bdf_list_len == 0:
|
||||
print("const struct vmsix_on_msi_info vmsix_on_msi_devs[MAX_VMSIX_ON_MSI_PDEVS_NUM];", file=config)
|
||||
break
|
||||
for i in range(bdf_list_len):
|
||||
b = bdf_list[i].split(":")[0]
|
||||
d = bdf_list[i].split(":")[1].split(".")[0]
|
||||
f = bdf_list[i].split(".")[1]
|
||||
print("#define VMSIX_ON_MSI_DEV{}\t.bdf.bits = {{.b = 0x{}U, .d = 0x{}U, .f =0x{}U}},".format(i, b, d, f), file=config)
|
||||
|
||||
for i in range(bdf_list_len):
|
||||
if i == 0:
|
||||
print("const struct vmsix_on_msi_info vmsix_on_msi_devs[MAX_VMSIX_ON_MSI_PDEVS_NUM] = {", file=config)
|
||||
print("\t{{VMSIX_ON_MSI_DEV{}}},".format(i), file=config)
|
||||
if i == (bdf_list_len - 1):
|
||||
print("};", file=config)
|
||||
|
||||
|
||||
def generate_file(config):
|
||||
"""
|
||||
Start to generate board.c
|
||||
:param config: it is a file pointer of board information for writing to
|
||||
"""
|
||||
err_dic = {}
|
||||
print("{0}".format(board_cfg_lib.HEADER_LICENSE), file=config)
|
||||
|
||||
# insert bios info into board.c
|
||||
board_cfg_lib.handle_bios_info(config)
|
||||
print(INCLUDE_HEADER, file=config)
|
||||
|
||||
# start to parse DMAR info
|
||||
gen_dmar_structure(config)
|
||||
|
||||
# start to parse RDT resource info
|
||||
err_dic = gen_rdt_res(config)
|
||||
if err_dic:
|
||||
return err_dic
|
||||
|
||||
# start to parse PX/CX info
|
||||
gen_px_cx(config)
|
||||
|
||||
# gen hide pci info for platform
|
||||
gen_pci_hide(config)
|
||||
|
||||
# gen known caps of pci dev info for platform
|
||||
gen_known_caps_pci_devs(config)
|
||||
|
||||
return err_dic
|
148
misc/config_tools/board_config/board_cfg_gen.py
Executable file
148
misc/config_tools/board_config/board_cfg_gen.py
Executable file
@@ -0,0 +1,148 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'library'))
|
||||
import board_cfg_lib
|
||||
import board_c
|
||||
import board_info_h
|
||||
import pci_devices_h
|
||||
import acpi_platform_h
|
||||
import misc_cfg_h
|
||||
import common
|
||||
import vbar_base_h
|
||||
|
||||
ACRN_PATH = common.SOURCE_ROOT_DIR
|
||||
ACRN_CONFIG_DEF = ACRN_PATH + "misc/config_tools/data/"
|
||||
|
||||
ACRN_DEFAULT_ACPI = ACRN_PATH + "hypervisor/include/arch/x86/default_acpi_info.h"
|
||||
GEN_FILE = ["pci_devices.h", "board.c", "platform_acpi_info.h", "misc_cfg.h",
|
||||
"board_info.h", "vbar_base.h"]
|
||||
|
||||
|
||||
def main(args):
|
||||
"""
|
||||
This is main function to start generate source code related with board
|
||||
:param args: it is a command line args for the script
|
||||
"""
|
||||
err_dic = {}
|
||||
|
||||
(err_dic, params) = common.get_param(args)
|
||||
if err_dic:
|
||||
return err_dic
|
||||
|
||||
# check env
|
||||
err_dic = common.prepare()
|
||||
if err_dic:
|
||||
return err_dic
|
||||
|
||||
common.BOARD_INFO_FILE = params['--board']
|
||||
common.SCENARIO_INFO_FILE = params['--scenario']
|
||||
common.get_vm_num(params['--scenario'])
|
||||
common.get_vm_types()
|
||||
|
||||
if common.VM_COUNT > common.MAX_VM_NUM:
|
||||
err_dic['vm count'] = "The vm count in config xml should be less or equal {}!".format(common.MAX_VM_NUM)
|
||||
return err_dic
|
||||
|
||||
# check if this is the scenario config which matched board info
|
||||
# get board name
|
||||
(err_dic, board) = common.get_board_name()
|
||||
if err_dic:
|
||||
return err_dic
|
||||
|
||||
(err_dic, scenario) = common.get_scenario_name()
|
||||
if err_dic:
|
||||
return err_dic
|
||||
board_cfg_lib.BOARD_NAME = board
|
||||
|
||||
# check if this is the scenario config which matched board info
|
||||
(err_dic, status) = common.is_config_file_match()
|
||||
if not status:
|
||||
err_dic['board config'] = "The board xml file does not match scenario xml file!"
|
||||
return err_dic
|
||||
|
||||
output = ''
|
||||
if params['--out']:
|
||||
if os.path.isabs(params['--out']):
|
||||
output = params['--out']
|
||||
else:
|
||||
output = ACRN_PATH + params['--out']
|
||||
else:
|
||||
output = ACRN_CONFIG_DEF
|
||||
|
||||
board_fix_dir = os.path.join(output, "boards/" + board + '/')
|
||||
scen_board_dir = os.path.join(output, "scenarios/" + scenario + "/" + board + '/')
|
||||
common.mkdir(board_fix_dir)
|
||||
common.mkdir(scen_board_dir)
|
||||
|
||||
config_pci = board_fix_dir + GEN_FILE[0]
|
||||
config_board = board_fix_dir + GEN_FILE[1]
|
||||
config_acpi = board_fix_dir + GEN_FILE[2]
|
||||
config_board_h = board_fix_dir + GEN_FILE[4]
|
||||
config_misc_cfg = scen_board_dir + GEN_FILE[3]
|
||||
config_vbar_base = scen_board_dir + GEN_FILE[5]
|
||||
|
||||
# generate pci_devices.h
|
||||
with open(config_pci, 'w+') as config:
|
||||
pci_devices_h.generate_file(config)
|
||||
|
||||
# generate board_info.h
|
||||
with open(config_board_h, 'w+') as config:
|
||||
err_dic = board_info_h.generate_file(config)
|
||||
if err_dic:
|
||||
return err_dic
|
||||
|
||||
# generate board.c
|
||||
with open(config_board, 'w+') as config:
|
||||
err_dic = board_c.generate_file(config)
|
||||
if err_dic:
|
||||
return err_dic
|
||||
|
||||
# generate vbar_base.h
|
||||
with open(config_vbar_base, 'w+') as config:
|
||||
vbar_base_h.generate_file(config)
|
||||
|
||||
# generate platform_acpi_info.h
|
||||
with open(config_acpi, 'w+') as config:
|
||||
acpi_platform_h.generate_file(config, ACRN_DEFAULT_ACPI)
|
||||
|
||||
# generate misc_cfg.h
|
||||
with open(config_misc_cfg, 'w+') as config:
|
||||
err_dic = misc_cfg_h.generate_file(config)
|
||||
if err_dic:
|
||||
return err_dic
|
||||
|
||||
if not err_dic:
|
||||
print("Board configurations for {} is generated successfully.".format(board))
|
||||
else:
|
||||
print("Board configurations for {} is generated failed.".format(board))
|
||||
|
||||
return err_dic
|
||||
|
||||
|
||||
def ui_entry_api(board_info, scenario_info, out=''):
|
||||
|
||||
arg_list = ['board_cfg_gen.py', '--board', board_info, '--scenario', scenario_info, '--out', out]
|
||||
|
||||
err_dic = common.prepare()
|
||||
if err_dic:
|
||||
return err_dic
|
||||
|
||||
err_dic = main(arg_list)
|
||||
|
||||
return err_dic
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
ARGS = sys.argv
|
||||
err_dic = main(ARGS)
|
||||
if err_dic:
|
||||
for err_k, err_v in err_dic.items():
|
||||
common.print_red("{}: {}".format(err_k, err_v), err=True)
|
||||
sys.exit(1 if err_dic else 0)
|
113
misc/config_tools/board_config/board_info_h.py
Normal file
113
misc/config_tools/board_config/board_info_h.py
Normal file
@@ -0,0 +1,113 @@
|
||||
# Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
import common
|
||||
import board_cfg_lib
|
||||
import scenario_cfg_lib
|
||||
|
||||
BOARD_INFO_DEFINE="""#ifndef BOARD_INFO_H
|
||||
#define BOARD_INFO_H
|
||||
"""
|
||||
|
||||
BOARD_INFO_ENDIF="""
|
||||
#endif /* BOARD_INFO_H */"""
|
||||
|
||||
def gen_known_caps_pci_head(config):
|
||||
|
||||
bdf_list_len = 0
|
||||
known_caps_pci_devs = board_cfg_lib.get_known_caps_pci_devs()
|
||||
for dev,bdf_list in known_caps_pci_devs.items():
|
||||
if dev == "VMSIX":
|
||||
bdf_list_len = len(bdf_list)
|
||||
print("#define MAX_VMSIX_ON_MSI_PDEVS_NUM\t{}U".format(bdf_list_len), file=config)
|
||||
|
||||
|
||||
def find_hi_mmio_window(config):
|
||||
|
||||
i_cnt = 0
|
||||
mmio_min = 0
|
||||
mmio_max = 0
|
||||
is_hi_mmio = False
|
||||
|
||||
iomem_lines = board_cfg_lib.get_info(common.BOARD_INFO_FILE, "<IOMEM_INFO>", "</IOMEM_INFO>")
|
||||
|
||||
for line in iomem_lines:
|
||||
if "PCI Bus" not in line:
|
||||
continue
|
||||
|
||||
line_start_addr = int(line.split('-')[0], 16)
|
||||
line_end_addr = int(line.split('-')[1].split()[0], 16)
|
||||
if line_start_addr < common.SIZE_4G and line_end_addr < common.SIZE_4G:
|
||||
continue
|
||||
elif line_start_addr < common.SIZE_4G and line_end_addr >= common.SIZE_4G:
|
||||
i_cnt += 1
|
||||
is_hi_mmio = True
|
||||
mmio_min = common.SIZE_4G
|
||||
mmio_max = line_end_addr
|
||||
continue
|
||||
|
||||
is_hi_mmio = True
|
||||
if i_cnt == 0:
|
||||
mmio_min = line_start_addr
|
||||
mmio_max = line_end_addr
|
||||
|
||||
if mmio_max < line_end_addr:
|
||||
mmio_max = line_end_addr
|
||||
i_cnt += 1
|
||||
|
||||
print("", file=config)
|
||||
if is_hi_mmio:
|
||||
print("#define HI_MMIO_START\t\t\t0x%xUL" % common.round_down(mmio_min, common.SIZE_G), file=config)
|
||||
print("#define HI_MMIO_END\t\t\t0x%xUL" % common.round_up(mmio_max, common.SIZE_G), file=config)
|
||||
else:
|
||||
print("#define HI_MMIO_START\t\t\t~0UL", file=config)
|
||||
print("#define HI_MMIO_END\t\t\t0UL", file=config)
|
||||
print("#define HI_MMIO_SIZE\t\t\t{}UL".format(hex(board_cfg_lib.HI_MMIO_OFFSET)), file=config)
|
||||
|
||||
|
||||
def generate_file(config):
|
||||
# get cpu processor list
|
||||
cpu_list = board_cfg_lib.get_processor_info()
|
||||
max_cpu_num = len(cpu_list)
|
||||
|
||||
# start to generate board_info.h
|
||||
print("{0}".format(board_cfg_lib.HEADER_LICENSE), file=config)
|
||||
print(BOARD_INFO_DEFINE, file=config)
|
||||
|
||||
# define CONFIG_MAX_PCPCU_NUM
|
||||
print("#define MAX_PCPU_NUM\t\t\t{}U".format(max_cpu_num), file=config)
|
||||
|
||||
# define MAX_VMSIX_ON_MSI_PDEVS_NUM
|
||||
gen_known_caps_pci_head(config)
|
||||
|
||||
# define MAX_HIDDEN_PDEVS_NUM
|
||||
if board_cfg_lib.BOARD_NAME in list(board_cfg_lib.KNOWN_HIDDEN_PDEVS_BOARD_DB):
|
||||
print("#define MAX_HIDDEN_PDEVS_NUM\t\t{}U".format(len(board_cfg_lib.KNOWN_HIDDEN_PDEVS_BOARD_DB[board_cfg_lib.BOARD_NAME])), file=config)
|
||||
else:
|
||||
print("#define MAX_HIDDEN_PDEVS_NUM\t\t0U", file=config)
|
||||
|
||||
# generate HI_MMIO_START/HI_MMIO_END
|
||||
find_hi_mmio_window(config)
|
||||
|
||||
p2sb = common.get_leaf_tag_map_bool(common.SCENARIO_INFO_FILE, "mmio_resources", "p2sb")
|
||||
if (common.VM_TYPES.get(0) is not None and
|
||||
scenario_cfg_lib.VM_DB[common.VM_TYPES[0]]['load_type'] == "PRE_LAUNCHED_VM"
|
||||
and board_cfg_lib.is_p2sb_passthru_possible()
|
||||
and p2sb.get(0, False)):
|
||||
print("", file=config)
|
||||
print("#define P2SB_VGPIO_DM_ENABLED", file=config)
|
||||
|
||||
hpa = board_cfg_lib.find_p2sb_bar_addr()
|
||||
print("#define P2SB_BAR_ADDR\t\t\t0x{:X}UL".format(hpa), file=config)
|
||||
gpa = common.hpa2gpa(0, hpa, 0x1000000)
|
||||
print("#define P2SB_BAR_ADDR_GPA\t\t0x{:X}UL".format(gpa), file=config)
|
||||
print("#define P2SB_BAR_SIZE\t\t\t0x1000000UL", file=config)
|
||||
|
||||
if board_cfg_lib.is_matched_board(("ehl-crb-b")):
|
||||
print("", file=config)
|
||||
print("#define P2SB_BASE_GPIO_PORT_ID\t\t0x69U", file=config)
|
||||
print("#define P2SB_MAX_GPIO_COMMUNITIES\t0x6U", file=config)
|
||||
|
||||
print(BOARD_INFO_ENDIF, file=config)
|
393
misc/config_tools/board_config/misc_cfg_h.py
Normal file
393
misc/config_tools/board_config/misc_cfg_h.py
Normal file
@@ -0,0 +1,393 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
import common
|
||||
import board_cfg_lib
|
||||
import scenario_cfg_lib
|
||||
|
||||
MISC_CFG_HEADER = """#ifndef MISC_CFG_H
|
||||
#define MISC_CFG_H"""
|
||||
|
||||
MISC_CFG_END = """#endif /* MISC_CFG_H */"""
|
||||
|
||||
|
||||
class Vuart:
|
||||
|
||||
t_vm_id = {}
|
||||
t_vuart_id = {}
|
||||
v_type = {}
|
||||
v_base = {}
|
||||
v_irq = {}
|
||||
|
||||
|
||||
def sos_bootarg_diff(sos_cmdlines, config):
|
||||
|
||||
if sos_cmdlines:
|
||||
sos_len = len(sos_cmdlines)
|
||||
i = 0
|
||||
for sos_cmdline in sos_cmdlines:
|
||||
if not sos_cmdline:
|
||||
continue
|
||||
|
||||
i += 1
|
||||
if i == 1:
|
||||
if sos_len == 1:
|
||||
print('#define SOS_BOOTARGS_DIFF\t"{}"'.format(sos_cmdline.strip('"')), file=config)
|
||||
else:
|
||||
print('#define SOS_BOOTARGS_DIFF\t"{} " \\'.format(sos_cmdline), file=config)
|
||||
else:
|
||||
if i < sos_len:
|
||||
print('\t\t\t\t"{} "\t\\'.format(sos_cmdline), file=config)
|
||||
else:
|
||||
print('\t\t\t\t"{}"'.format(sos_cmdline), file=config)
|
||||
|
||||
|
||||
def parse_boot_info():
|
||||
|
||||
err_dic = {}
|
||||
|
||||
if 'SOS_VM' in common.VM_TYPES.values():
|
||||
sos_cmdlines = list(common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "board_private", "bootargs").values())
|
||||
sos_rootfs = list(common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "board_private", "rootfs").values())
|
||||
(err_dic, vuart0_dic, vuart1_dic) = scenario_cfg_lib.get_sos_vuart_settings(launch_flag=False)
|
||||
else:
|
||||
sos_cmdlines = list(common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "os_config", "bootargs").values())
|
||||
|
||||
sos_rootfs = list(common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "os_config", "rootfs").values())
|
||||
(err_dic, vuart0_dic, vuart1_dic) = scenario_cfg_lib.get_sos_vuart_settings(launch_flag=False)
|
||||
|
||||
return (err_dic, sos_cmdlines, sos_rootfs, vuart0_dic, vuart1_dic)
|
||||
|
||||
|
||||
def clos_per_vm_gen(config):
|
||||
|
||||
clos_per_vm = {}
|
||||
clos_per_vm = common.get_leaf_tag_map(
|
||||
common.SCENARIO_INFO_FILE, "clos", "vcpu_clos")
|
||||
for i,clos_list_i in clos_per_vm.items():
|
||||
clos_config = scenario_cfg_lib.clos_assignment(clos_per_vm, i)
|
||||
print("#define VM{0}_VCPU_CLOS\t\t\t{1}".format(i, clos_config['clos_map']), file=config)
|
||||
|
||||
|
||||
def cpu_affinity_output(cpu_bits, i, config):
|
||||
|
||||
if "SOS_VM" == common.VM_TYPES[i]:
|
||||
print("", file=config)
|
||||
print("#define SOS_VM_CONFIG_CPU_AFFINITY\t{0}".format(
|
||||
cpu_bits['cpu_map']), file=config)
|
||||
else:
|
||||
print("#define VM{0}_CONFIG_CPU_AFFINITY\t{1}".format(
|
||||
i, cpu_bits['cpu_map']), file=config)
|
||||
|
||||
|
||||
def cpu_affinity_per_vm_gen(config):
|
||||
|
||||
cpus_per_vm = common.get_leaf_tag_map(
|
||||
common.SCENARIO_INFO_FILE, "cpu_affinity", "pcpu_id")
|
||||
|
||||
for vm_i,_ in common.VM_TYPES.items():
|
||||
cpu_bits = scenario_cfg_lib.cpus_assignment(cpus_per_vm, vm_i)
|
||||
cpu_affinity_output(cpu_bits, vm_i, config)
|
||||
|
||||
print("", file=config)
|
||||
|
||||
|
||||
def pci_dev_num_per_vm_gen(config):
|
||||
|
||||
pci_items = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "pci_devs", "pci_dev")
|
||||
pci_devs = scenario_cfg_lib.get_pt_pci_devs(pci_items)
|
||||
pt_pci_num = scenario_cfg_lib.get_pt_pci_num(pci_devs)
|
||||
|
||||
ivshmem_region = common.get_hv_item_tag(common.SCENARIO_INFO_FILE,
|
||||
"FEATURES", "IVSHMEM", "IVSHMEM_REGION")
|
||||
|
||||
shmem_enabled = common.get_hv_item_tag(common.SCENARIO_INFO_FILE,
|
||||
"FEATURES", "IVSHMEM", "IVSHMEM_ENABLED")
|
||||
|
||||
shmem_regions = scenario_cfg_lib.get_shmem_regions(ivshmem_region)
|
||||
shmem_num = scenario_cfg_lib.get_shmem_num(shmem_regions)
|
||||
|
||||
vuarts = common.get_vuart_info(common.SCENARIO_INFO_FILE)
|
||||
pci_vuarts_num = scenario_cfg_lib.get_pci_vuart_num(vuarts)
|
||||
|
||||
for vm_i,vm_type in common.VM_TYPES.items():
|
||||
num = 0
|
||||
if "POST_LAUNCHED_VM" == scenario_cfg_lib.VM_DB[vm_type]['load_type']:
|
||||
shmem_num_i = 0
|
||||
pci_vuart_num = pci_vuarts_num[vm_i]
|
||||
if shmem_enabled == 'y' and vm_i in shmem_num.keys():
|
||||
shmem_num_i = shmem_num[vm_i]
|
||||
num = shmem_num_i + pci_vuart_num
|
||||
elif "PRE_LAUNCHED_VM" == scenario_cfg_lib.VM_DB[vm_type]['load_type']:
|
||||
shmem_num_i = 0
|
||||
if shmem_enabled == 'y' and vm_i in shmem_num.keys():
|
||||
shmem_num_i = shmem_num[vm_i]
|
||||
num = pt_pci_num[vm_i] + shmem_num_i + pci_vuarts_num[vm_i]
|
||||
if pt_pci_num[vm_i] > 0 or shmem_num_i > 0 or pci_vuarts_num[vm_i] > 0:
|
||||
# if there is passthrough device or ivshmem, vhostbridge is needed
|
||||
num += 1
|
||||
elif "SOS_VM" == scenario_cfg_lib.VM_DB[vm_type]['load_type']:
|
||||
continue
|
||||
if num > 0:
|
||||
print("#define VM{}_CONFIG_PCI_DEV_NUM\t{}U".format(vm_i, num), file=config)
|
||||
|
||||
print("", file=config)
|
||||
|
||||
|
||||
def split_cmdline(cmd_str, config):
|
||||
|
||||
cmd_list = [i for i in cmd_str.strip('"').split()]
|
||||
if not cmd_list: return
|
||||
|
||||
last_idx = len(cmd_list) - 1
|
||||
for idx, cmd_arg in enumerate(cmd_list):
|
||||
if idx == 0:
|
||||
print('"', end="", file=config)
|
||||
elif idx % 4 == 0:
|
||||
print("\\\n", end="", file=config)
|
||||
|
||||
if idx == last_idx:
|
||||
print('{}"'.format(cmd_arg), file=config)
|
||||
else:
|
||||
print('{} '.format(cmd_arg), end="", file=config)
|
||||
|
||||
|
||||
def boot_args_per_vm_gen(config):
|
||||
kern_args = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "os_config", "bootargs")
|
||||
|
||||
for vm_i,vm_type in common.VM_TYPES.items():
|
||||
if "PRE_LAUNCHED_VM" == scenario_cfg_lib.VM_DB[vm_type]['load_type']:
|
||||
if vm_i in kern_args.keys() and kern_args[vm_i]:
|
||||
print("#define VM{}_BOOT_ARGS\t".format(vm_i), end="", file=config)
|
||||
split_cmdline(kern_args[vm_i].strip(), config)
|
||||
print("", file=config)
|
||||
|
||||
print("", file=config)
|
||||
|
||||
|
||||
def pt_intx_num_vm0_gen(config):
|
||||
|
||||
phys_gsi, virt_gsi = common.get_pt_intx_table(common.SCENARIO_INFO_FILE)
|
||||
|
||||
if (board_cfg_lib.is_matched_board(("ehl-crb-b"))
|
||||
and phys_gsi.get(0) is not None
|
||||
and len(phys_gsi[0]) > 0):
|
||||
print("#define VM0_PT_INTX_NUM\t{}U".format(len(phys_gsi[0])), file=config)
|
||||
else:
|
||||
print("#define VM0_PT_INTX_NUM\t0U", file=config)
|
||||
|
||||
print("", file=config)
|
||||
|
||||
|
||||
def generate_file(config):
|
||||
"""
|
||||
Start to generate board.c
|
||||
:param config: it is a file pointer of board information for writing to
|
||||
"""
|
||||
board_cfg_lib.get_valid_irq(common.BOARD_INFO_FILE)
|
||||
|
||||
# get the vuart0/vuart1 which user chosed from scenario.xml of board_private section
|
||||
(err_dic, ttys_n) = board_cfg_lib.parser_hv_console()
|
||||
if err_dic:
|
||||
return err_dic
|
||||
|
||||
# parse sos_bootargs/rootfs/console
|
||||
(err_dic, sos_cmdlines, sos_rootfs, vuart0_dic, vuart1_dic) = parse_boot_info()
|
||||
if err_dic:
|
||||
return err_dic
|
||||
|
||||
if vuart0_dic:
|
||||
# parse to get poart/base of vuart0/vuart1
|
||||
vuart0_port_base = board_cfg_lib.LEGACY_TTYS[list(vuart0_dic.keys())[0]]
|
||||
vuart0_irq = vuart0_dic[list(vuart0_dic.keys())[0]]
|
||||
|
||||
vuart1_port_base = board_cfg_lib.LEGACY_TTYS[list(vuart1_dic.keys())[0]]
|
||||
vuart1_irq = vuart1_dic[list(vuart1_dic.keys())[0]]
|
||||
|
||||
# parse the setting ttys vuatx dic: {vmid:base/irq}
|
||||
vuart0_setting = Vuart()
|
||||
vuart1_setting = Vuart()
|
||||
vuart0_setting = common.get_vuart_info_id(common.SCENARIO_INFO_FILE, 0)
|
||||
vuart1_setting = common.get_vuart_info_id(common.SCENARIO_INFO_FILE, 1)
|
||||
|
||||
# sos command lines information
|
||||
sos_cmdlines = [i for i in sos_cmdlines[0].split() if i != '']
|
||||
|
||||
# add maxcpus parameter into sos cmdlines if there are pre-launched VMs
|
||||
pcpu_list = board_cfg_lib.get_processor_info()
|
||||
cpu_affinity = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "cpu_affinity", "pcpu_id")
|
||||
pre_cpu_list = []
|
||||
sos_cpu_num = 0
|
||||
for vmid, cpu_list in cpu_affinity.items():
|
||||
if vmid in common.VM_TYPES and cpu_list != [None]:
|
||||
vm_type = common.VM_TYPES[vmid]
|
||||
load_type = ''
|
||||
if vm_type in scenario_cfg_lib.VM_DB:
|
||||
load_type = scenario_cfg_lib.VM_DB[vm_type]['load_type']
|
||||
if load_type == "PRE_LAUNCHED_VM":
|
||||
pre_cpu_list += cpu_list
|
||||
elif load_type == "SOS_VM":
|
||||
sos_cpu_num += len(cpu_list)
|
||||
if sos_cpu_num == 0:
|
||||
sos_cpu_num_max = len(list(set(pcpu_list) - set(pre_cpu_list)))
|
||||
else:
|
||||
sos_cpu_num_max = sos_cpu_num
|
||||
if sos_cpu_num_max > 0:
|
||||
sos_cmdlines.append('maxcpus='+str(sos_cpu_num_max))
|
||||
|
||||
# get native rootfs list from board_info.xml
|
||||
(root_devs, root_dev_num) = board_cfg_lib.get_rootfs(common.BOARD_INFO_FILE)
|
||||
|
||||
# start to generate misc_cfg.h
|
||||
print("{0}".format(board_cfg_lib.HEADER_LICENSE), file=config)
|
||||
print("{}".format(MISC_CFG_HEADER), file=config)
|
||||
print("", file=config)
|
||||
|
||||
# define rootfs with macro
|
||||
#for i in range(root_dev_num):
|
||||
# print('#define ROOTFS_{}\t\t"root={} "'.format(i, root_devs[i]), file=config)
|
||||
|
||||
# sos rootfs and console
|
||||
if "SOS_VM" in common.VM_TYPES.values():
|
||||
print('#define SOS_ROOTFS\t\t"root={} "'.format(sos_rootfs[0]), file=config)
|
||||
if ttys_n:
|
||||
print('#define SOS_CONSOLE\t\t"console={} "'.format(ttys_n), file=config)
|
||||
else:
|
||||
print('#define SOS_CONSOLE\t\t" "', file=config)
|
||||
|
||||
# sos com base/irq
|
||||
i_type = 0
|
||||
for vm_i,vm_type in common.VM_TYPES.items():
|
||||
if vm_type == "SOS_VM":
|
||||
i_type = vm_i
|
||||
break
|
||||
|
||||
if "SOS_VM" in common.VM_TYPES.values():
|
||||
if vuart0_dic:
|
||||
print("#define SOS_COM1_BASE\t\t{}U".format(vuart0_port_base), file=config)
|
||||
print("#define SOS_COM1_IRQ\t\t{}U".format(vuart0_irq), file=config)
|
||||
else:
|
||||
print("#define SOS_COM1_BASE\t\t0U", file=config)
|
||||
print("#define SOS_COM1_IRQ\t\t0U", file=config)
|
||||
|
||||
if vuart1_setting[i_type]['base'] != "INVALID_COM_BASE":
|
||||
print("#define SOS_COM2_BASE\t\t{}U".format(vuart1_port_base), file=config)
|
||||
print("#define SOS_COM2_IRQ\t\t{}U".format(vuart1_irq), file=config)
|
||||
|
||||
# sos boot command line
|
||||
print("", file=config)
|
||||
|
||||
if "SOS_VM" in common.VM_TYPES.values():
|
||||
sos_bootarg_diff(sos_cmdlines, config)
|
||||
print("", file=config)
|
||||
|
||||
cpu_affinity_per_vm_gen(config)
|
||||
|
||||
common_clos_max = board_cfg_lib.get_common_clos_max()
|
||||
max_mba_clos_entries = common_clos_max
|
||||
max_cache_clos_entries = common_clos_max
|
||||
|
||||
comments_max_clos = '''
|
||||
/*
|
||||
* The maximum CLOS that is allowed by ACRN hypervisor,
|
||||
* its value is set to be least common Max CLOS (CPUID.(EAX=0x10,ECX=ResID):EDX[15:0])
|
||||
* among all supported RDT resources in the platform. In other words, it is
|
||||
* min(maximum CLOS of L2, L3 and MBA). This is done in order to have consistent
|
||||
* CLOS allocations between all the RDT resources.
|
||||
*/'''
|
||||
|
||||
comments_max_mba_clos = '''
|
||||
/*
|
||||
* Max number of Cache Mask entries corresponding to each CLOS.
|
||||
* This can vary if CDP is enabled vs disabled, as each CLOS entry
|
||||
* will have corresponding cache mask values for Data and Code when
|
||||
* CDP is enabled.
|
||||
*/'''
|
||||
|
||||
comments_max_cache_clos = '''
|
||||
/* Max number of MBA delay entries corresponding to each CLOS. */'''
|
||||
|
||||
if board_cfg_lib.is_cdp_enabled():
|
||||
max_cache_clos_entries_cdp_enable = 2 * common_clos_max
|
||||
(res_info, rdt_res_clos_max, clos_max_mask_list) = board_cfg_lib.clos_info_parser(common.BOARD_INFO_FILE)
|
||||
common_clos_max_cdp_disable = min(rdt_res_clos_max)
|
||||
|
||||
print("#ifdef CONFIG_RDT_ENABLED", file=config)
|
||||
print("#ifdef CONFIG_CDP_ENABLED", file=config)
|
||||
print(comments_max_clos, file=config)
|
||||
print("#define HV_SUPPORTED_MAX_CLOS\t{}U".format(common_clos_max), file=config)
|
||||
|
||||
print(comments_max_cache_clos, file=config)
|
||||
print("#define MAX_CACHE_CLOS_NUM_ENTRIES\t{}U".format(max_cache_clos_entries_cdp_enable), file=config)
|
||||
|
||||
print("#else", file=config)
|
||||
print(comments_max_clos, file=config)
|
||||
print("#define HV_SUPPORTED_MAX_CLOS\t{}U".format(common_clos_max_cdp_disable), file=config)
|
||||
|
||||
print(comments_max_cache_clos, file=config)
|
||||
print("#define MAX_CACHE_CLOS_NUM_ENTRIES\t{}U".format(max_cache_clos_entries), file=config)
|
||||
print("#endif", file=config)
|
||||
|
||||
print(comments_max_mba_clos, file=config)
|
||||
print("#define MAX_MBA_CLOS_NUM_ENTRIES\t{}U".format(max_mba_clos_entries), file=config)
|
||||
else:
|
||||
print("#ifdef CONFIG_RDT_ENABLED", file=config)
|
||||
print(comments_max_clos, file=config)
|
||||
print("#define HV_SUPPORTED_MAX_CLOS\t{}U".format(common_clos_max), file=config)
|
||||
|
||||
print(comments_max_mba_clos, file=config)
|
||||
print("#define MAX_MBA_CLOS_NUM_ENTRIES\t{}U".format(max_mba_clos_entries), file=config)
|
||||
|
||||
print(comments_max_cache_clos, file=config)
|
||||
print("#define MAX_CACHE_CLOS_NUM_ENTRIES\t{}U".format(max_cache_clos_entries), file=config)
|
||||
if not board_cfg_lib.is_rdt_supported():
|
||||
print("#endif", file=config)
|
||||
|
||||
print("", file=config)
|
||||
|
||||
if board_cfg_lib.is_rdt_supported():
|
||||
(rdt_resources, rdt_res_clos_max, _) = board_cfg_lib.clos_info_parser(common.BOARD_INFO_FILE)
|
||||
cat_mask_list = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "RDT", "CLOS_MASK")
|
||||
mba_delay_list = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "RDT", "MBA_DELAY")
|
||||
idx = 0
|
||||
for mba_delay_mask in mba_delay_list:
|
||||
print("#define MBA_MASK_{}\t\t\t{}U".format(idx, mba_delay_mask), file=config)
|
||||
idx += 1
|
||||
|
||||
idx = 0
|
||||
for cat_mask in cat_mask_list:
|
||||
print("#define CLOS_MASK_{}\t\t\t{}U".format(idx, cat_mask), file=config)
|
||||
idx += 1
|
||||
print("", file=config)
|
||||
|
||||
clos_per_vm_gen(config)
|
||||
print("#endif", file=config)
|
||||
print("", file=config)
|
||||
|
||||
vm0_pre_launch = False
|
||||
common.get_vm_types()
|
||||
for vm_idx,vm_type in common.VM_TYPES.items():
|
||||
if vm_idx == 0 and scenario_cfg_lib.VM_DB[vm_type]['load_type'] == "PRE_LAUNCHED_VM":
|
||||
vm0_pre_launch = True
|
||||
|
||||
if vm0_pre_launch and board_cfg_lib.is_tpm_passthru():
|
||||
tpm2_passthru_enabled = common.get_leaf_tag_map_bool(common.SCENARIO_INFO_FILE, "mmio_resources", "TPM2")
|
||||
if 0 in tpm2_passthru_enabled and tpm2_passthru_enabled[0]:
|
||||
print("#define VM0_PASSTHROUGH_TPM", file=config)
|
||||
print("#define VM0_TPM_BUFFER_BASE_ADDR 0xFED40000UL", file=config)
|
||||
gpa = common.hpa2gpa(0, 0xFED40000, 0x5000)
|
||||
print("#define VM0_TPM_BUFFER_BASE_ADDR_GPA 0x{:X}UL".format(gpa), file=config)
|
||||
print("#define VM0_TPM_BUFFER_SIZE 0x5000UL", file=config)
|
||||
print("", file=config)
|
||||
|
||||
pci_dev_num_per_vm_gen(config)
|
||||
|
||||
boot_args_per_vm_gen(config)
|
||||
|
||||
pt_intx_num_vm0_gen(config)
|
||||
|
||||
print("{}".format(MISC_CFG_END), file=config)
|
||||
|
||||
return err_dic
|
66
misc/config_tools/board_config/pci_devices_h.py
Normal file
66
misc/config_tools/board_config/pci_devices_h.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
import collections
|
||||
import board_cfg_lib
|
||||
import common
|
||||
|
||||
PCI_HEADER = r"""
|
||||
#ifndef PCI_DEVICES_H_
|
||||
#define PCI_DEVICES_H_"""
|
||||
PCI_END_HEADER = r"""
|
||||
#endif /* PCI_DEVICES_H_ */"""
|
||||
|
||||
def write_pbdf(i_cnt, bdf, bar_attr, config):
|
||||
"""
|
||||
Parser and generate pbdf
|
||||
:param i_cnt: the number of pci devices have the same PCI sub class name
|
||||
:param bdf: it is a string what contains BDF
|
||||
:param bar_attr: it is a class, contains PIC bar attribute
|
||||
:param config: it is a file pointer of pci information for writing to
|
||||
"""
|
||||
tmp_sub_name = board_cfg_lib.get_sub_pci_name(i_cnt, bar_attr)
|
||||
board_cfg_lib.PCI_DEV_BAR_DESC.pci_dev_dic[bdf].name_w_i_cnt = tmp_sub_name
|
||||
|
||||
bus = int(bdf.split(':')[0], 16)
|
||||
dev = int(bdf.split(':')[1].split('.')[0], 16)
|
||||
fun = int(bdf.split('.')[1], 16)
|
||||
print("#define %-32s" % tmp_sub_name, end="", file=config)
|
||||
print(" .pbdf.bits = {{.b = 0x{:02X}U, .d = 0x{:02X}U, .f = 0x{:02X}U}}".format(
|
||||
bus, dev, fun), file=config)
|
||||
|
||||
|
||||
def generate_file(config):
|
||||
"""
|
||||
Get PCI device and generate pci_devices.h
|
||||
:param config: it is a file pointer of pci information for writing to
|
||||
"""
|
||||
# write the license into pci
|
||||
print("{0}".format(board_cfg_lib.HEADER_LICENSE), file=config)
|
||||
|
||||
# add bios and base board info
|
||||
board_cfg_lib.handle_bios_info(config)
|
||||
|
||||
# write the header into pci
|
||||
print("{0}".format(PCI_HEADER), file=config)
|
||||
|
||||
board_cfg_lib.parser_pci()
|
||||
|
||||
compared_bdf = []
|
||||
for cnt_sub_name in board_cfg_lib.SUB_NAME_COUNT.keys():
|
||||
i_cnt = 0
|
||||
for bdf, bar_attr in board_cfg_lib.PCI_DEV_BAR_DESC.pci_dev_dic.items():
|
||||
if cnt_sub_name == bar_attr.name and bdf not in compared_bdf:
|
||||
compared_bdf.append(bdf)
|
||||
else:
|
||||
continue
|
||||
|
||||
print("",file=config)
|
||||
write_pbdf(i_cnt, bdf, bar_attr, config)
|
||||
|
||||
i_cnt += 1
|
||||
|
||||
# write the end to the pci devices
|
||||
print("{0}".format(PCI_END_HEADER), file=config)
|
449
misc/config_tools/board_config/vbar_base_h.py
Normal file
449
misc/config_tools/board_config/vbar_base_h.py
Normal file
@@ -0,0 +1,449 @@
|
||||
# Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
import re
|
||||
from collections import namedtuple
|
||||
|
||||
import common
|
||||
import board_cfg_lib
|
||||
import scenario_cfg_lib
|
||||
|
||||
VBAR_INFO_DEFINE="""#ifndef VBAR_BASE_H_
|
||||
#define VBAR_BASE_H_
|
||||
"""
|
||||
|
||||
VBAR_INFO_ENDIF="""#endif /* VBAR_BASE_H_ */"""
|
||||
|
||||
# Constants for ivshmem
|
||||
BAR0_SHEMEM_SIZE = 4*common.SIZE_K
|
||||
BAR1_SHEMEM_SIZE = 4*common.SIZE_K
|
||||
BAR0_SHEMEM_ALIGNMENT = 4*common.SIZE_K
|
||||
BAR1_SHEMEM_ALIGNMENT = 4*common.SIZE_K
|
||||
BAR2_SHEMEM_ALIGNMENT = 2*common.SIZE_M
|
||||
|
||||
# Constants for pci vuart
|
||||
PCI_VUART_VBAR0_SIZE = 4*common.SIZE_K
|
||||
PCI_VUART_VBAR1_SIZE = 4*common.SIZE_K
|
||||
PCI_VUART_VBAR0_ALIGNMENT = 4*common.SIZE_K
|
||||
PCI_VUART_VBAR1_ALIGNMENT = 4*common.SIZE_K
|
||||
|
||||
# Constants for vmsix bar
|
||||
VMSIX_VBAR_SIZE = 4*common.SIZE_K
|
||||
VMSIX_VBAR_ALIGNMENT = VMSIX_VBAR_SIZE
|
||||
|
||||
|
||||
class MmioWindow(namedtuple(
|
||||
"MmioWindow", [
|
||||
"start",
|
||||
"end"])):
|
||||
|
||||
PATTERN = re.compile(r"\s*(?P<start>[0-9a-f]+)-(?P<end>[0-9a-f]+) ")
|
||||
|
||||
@classmethod
|
||||
def from_str(cls, value):
|
||||
if not isinstance(value, str):
|
||||
raise ValueError("value must be a str: {}".format(type(value)))
|
||||
|
||||
match = cls.PATTERN.fullmatch(value)
|
||||
if match:
|
||||
return MmioWindow(
|
||||
start=int(match.group("start"), 16),
|
||||
end=int(match.group("end"), 16))
|
||||
else:
|
||||
raise ValueError("not an mmio window: {!r}".format(value))
|
||||
|
||||
def overlaps(self, other):
|
||||
if not isinstance(other, MmioWindow):
|
||||
raise TypeError('overlaps() other must be an MmioWindow: {}'.format(type(other)))
|
||||
if other.end < self.start:
|
||||
return False
|
||||
if self.end < other.start:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def get_devs_per_vm_with_key(pci_devs, keywords):
|
||||
devicelist = {}
|
||||
for vm_i, pci_devs_list in pci_devs.items():
|
||||
devicelist[vm_i] = [
|
||||
d for d in pci_devs_list if d in keywords
|
||||
]
|
||||
return devicelist
|
||||
|
||||
|
||||
def write_vbar(i_cnt, bdf, pci_bar_dic, bar_attr, \
|
||||
pci_devs_per_vm, mmiolist_per_vm, sos_mmio_range,config):
|
||||
"""
|
||||
Parser and generate vbar
|
||||
:param i_cnt: the number of pci devices have the same PCI sub class name
|
||||
:param bdf: it is a string what contains BDF
|
||||
:param pci_bar_dic: it is a dictionary of pci vbar for those BDF
|
||||
:param bar_attr: it is a class, contains PIC bar attribute
|
||||
:param config: it is a file pointer of pci information for writing to
|
||||
"""
|
||||
align = ' ' * 54
|
||||
ptdev_mmio_str = ''
|
||||
|
||||
tmp_sub_name = board_cfg_lib.get_sub_pci_name(i_cnt, bar_attr)
|
||||
if bdf in pci_bar_dic.keys():
|
||||
bar_list = list(pci_bar_dic[bdf].keys())
|
||||
bar_len = len(bar_list)
|
||||
bar_num = 0
|
||||
bar_val = ""
|
||||
free = MmioWindow(0, 0)
|
||||
is_vmsix = False
|
||||
# If the device is vmsix device, find a free mmio window up to 4k size
|
||||
for vm_i in pci_devs_per_vm:
|
||||
if bdf in pci_devs_per_vm[vm_i]:
|
||||
if scenario_cfg_lib.VM_DB[common.VM_TYPES[vm_i]]['load_type'] == "PRE_LAUNCHED_VM":
|
||||
is_vmsix = True
|
||||
bar_len += 1
|
||||
# For pre-launched VM, the windows range is form 2G to 4G
|
||||
free = get_free_mmio([MmioWindow(start=common.SIZE_2G, end=common.SIZE_4G-1)], \
|
||||
mmiolist_per_vm[vm_i], VMSIX_VBAR_ALIGNMENT + VMSIX_VBAR_SIZE)
|
||||
free_vbar_start_addr = common.round_up(free.start, VMSIX_VBAR_ALIGNMENT)
|
||||
free_vbar_end_addr = free_vbar_start_addr + VMSIX_VBAR_SIZE - 1
|
||||
free = MmioWindow(free_vbar_start_addr, free_vbar_end_addr)
|
||||
mmiolist_per_vm[vm_i].append(free)
|
||||
mmiolist_per_vm[vm_i].sort()
|
||||
break
|
||||
for bar_i in bar_list:
|
||||
if not bar_attr.remappable:
|
||||
print("/* TODO: add {} 64bit BAR support */".format(tmp_sub_name), file=config)
|
||||
|
||||
bar_num += 1
|
||||
bar_val = pci_bar_dic[bdf][bar_i].addr
|
||||
if pci_bar_dic[bdf][bar_i].remapped:
|
||||
ptdev_mmio_str = 'PTDEV_HI_MMIO_START + '
|
||||
|
||||
if bar_num == bar_len:
|
||||
if bar_len == 1:
|
||||
print("#define %-38s" % (tmp_sub_name+"_VBAR"), " .vbar_base[{}] = {}{}UL" \
|
||||
.format(bar_i, ptdev_mmio_str, bar_val), file=config)
|
||||
else:
|
||||
print("{}.vbar_base[{}] = {}{}UL" \
|
||||
.format(align, bar_i, ptdev_mmio_str, bar_val), file=config)
|
||||
elif bar_num == 1:
|
||||
print("#define %-38s" % (tmp_sub_name+"_VBAR"), " .vbar_base[{}] = {}{}UL, \\".format(bar_i, ptdev_mmio_str, bar_val), file=config)
|
||||
else:
|
||||
print("{}.vbar_base[{}] = {}{}UL, \\".format(align, bar_i, ptdev_mmio_str, bar_val), file=config)
|
||||
if is_vmsix:
|
||||
next_bar_idx = find_next_bar(bar_val, bar_list)
|
||||
print("{}.vbar_base[{}] = {}{}UL".format(align, next_bar_idx, ptdev_mmio_str, hex(free.start)), file=config)
|
||||
print("", file=config)
|
||||
|
||||
|
||||
def find_next_bar(bar_val, bar_list):
|
||||
pci_lines = board_cfg_lib.get_info(common.BOARD_INFO_FILE, "<PCI_DEVICE>", "</PCI_DEVICE>")
|
||||
idx = bar_list[-1]
|
||||
for line in pci_lines:
|
||||
if bar_val.split('x')[1] in line:
|
||||
if "32-bit" in line:
|
||||
idx += 1
|
||||
break
|
||||
elif "64-bit" in line:
|
||||
idx += 2
|
||||
break
|
||||
if int(idx) > 5:
|
||||
raise ValueError("Not enough bar region, last bar region is {}".format(idx))
|
||||
return idx
|
||||
|
||||
|
||||
def write_vuart_vbar(mmiolist_per_vm, sos_mmio_range, config):
|
||||
# get legacy vuart information
|
||||
vuart0_setting = common.get_vuart_info_id(common.SCENARIO_INFO_FILE, 0)
|
||||
vuart1_setting = common.get_vuart_info_id(common.SCENARIO_INFO_FILE, 1)
|
||||
# get pci vuart information
|
||||
vuarts = common.get_vuart_info(common.SCENARIO_INFO_FILE)
|
||||
for vm_id in vuarts.keys():
|
||||
vm_type = common.VM_TYPES[vm_id]
|
||||
if scenario_cfg_lib.VM_DB[vm_type]['load_type'] == "POST_LAUNCHED_VM":
|
||||
continue
|
||||
for vuart_id in vuarts[vm_id].keys():
|
||||
if vuarts[vm_id][vuart_id]['base'] == "INVALID_PCI_BASE":
|
||||
continue
|
||||
# Skip pci vuart 0 if the legacy vuart 0 is enabled
|
||||
if vuart_id == 0 and vm_id in vuart0_setting \
|
||||
and vuart0_setting[vm_id]['base'] != "INVALID_COM_BASE":
|
||||
continue
|
||||
# Skip pci vuart 1 if the legacy vuart 1 is enabled
|
||||
if vuart_id == 1 and vm_id in vuart1_setting \
|
||||
and vuart1_setting[vm_id]['base'] != "INVALID_COM_BASE":
|
||||
continue
|
||||
free_bar0 = []
|
||||
free_bar1 = []
|
||||
# vuart decice requires 2 bars
|
||||
if scenario_cfg_lib.VM_DB[vm_type]['load_type'] == "SOS_VM":
|
||||
free_bar0 = get_free_mmio(sos_mmio_range, mmiolist_per_vm[vm_id], \
|
||||
PCI_VUART_VBAR0_SIZE + PCI_VUART_VBAR0_ALIGNMENT)
|
||||
free_bar0_start_addr = common.round_up(free_bar0.start, PCI_VUART_VBAR0_ALIGNMENT)
|
||||
free_bar0_end_addr = free_bar0_start_addr + PCI_VUART_VBAR0_SIZE - 1
|
||||
free_bar0 = MmioWindow(free_bar0_start_addr, free_bar0_end_addr)
|
||||
mmiolist_per_vm[vm_id].append(free_bar0)
|
||||
mmiolist_per_vm[vm_id].sort()
|
||||
free_bar1 = get_free_mmio(sos_mmio_range, mmiolist_per_vm[vm_id], \
|
||||
PCI_VUART_VBAR1_SIZE + PCI_VUART_VBAR1_ALIGNMENT)
|
||||
free_bar1_start_addr = common.round_up(free_bar1.start, PCI_VUART_VBAR1_ALIGNMENT)
|
||||
free_bar1_end_addr = free_bar1_start_addr + PCI_VUART_VBAR1_SIZE - 1
|
||||
free_bar1 = MmioWindow(free_bar1_start_addr, free_bar1_end_addr)
|
||||
mmiolist_per_vm[vm_id].append(free_bar1)
|
||||
mmiolist_per_vm[vm_id].sort()
|
||||
elif scenario_cfg_lib.VM_DB[vm_type]['load_type'] == "PRE_LAUNCHED_VM":
|
||||
free_bar0 = get_free_mmio([MmioWindow(start=common.SIZE_2G, end=common.SIZE_4G-1)], \
|
||||
mmiolist_per_vm[vm_id], PCI_VUART_VBAR0_SIZE + PCI_VUART_VBAR0_ALIGNMENT)
|
||||
free_bar0_start_addr = common.round_up(free_bar0.start, PCI_VUART_VBAR0_ALIGNMENT)
|
||||
free_bar0_end_addr = free_bar0_start_addr + PCI_VUART_VBAR0_SIZE - 1
|
||||
free_bar0 = MmioWindow(free_bar0_start_addr, free_bar0_end_addr)
|
||||
mmiolist_per_vm[vm_id].append(free_bar0)
|
||||
mmiolist_per_vm[vm_id].sort()
|
||||
free_bar1 = get_free_mmio([MmioWindow(start=common.SIZE_2G, end=common.SIZE_4G-1)], \
|
||||
mmiolist_per_vm[vm_id], PCI_VUART_VBAR1_SIZE + PCI_VUART_VBAR1_ALIGNMENT)
|
||||
free_bar1_start_addr = common.round_up(free_bar1.start, PCI_VUART_VBAR1_ALIGNMENT)
|
||||
free_bar1_end_addr = free_bar1_start_addr + PCI_VUART_VBAR1_SIZE - 1
|
||||
free_bar1 = MmioWindow(free_bar1_start_addr, free_bar1_end_addr)
|
||||
mmiolist_per_vm[vm_id].append(free_bar1)
|
||||
mmiolist_per_vm[vm_id].sort()
|
||||
print("#define VM%s" %(str(vm_id) + "_VUART_%-28s") % (str(vuart_id) + "_VBAR"),
|
||||
" .vbar_base[0] = {:#x}UL, \\".format(free_bar0.start), file=config)
|
||||
print("{}.vbar_base[1] = {:#x}UL".format(' ' * 54, free_bar1.start), file=config)
|
||||
print("", file=config)
|
||||
|
||||
|
||||
def write_ivshmem_vbar(mmiolist_per_vm, sos_mmio_range, config):
|
||||
for vm_id,vm_type in common.VM_TYPES.items():
|
||||
ivshmem_region = common.get_hv_item_tag(common.SCENARIO_INFO_FILE,
|
||||
"FEATURES", "IVSHMEM", "IVSHMEM_REGION")
|
||||
shmem_regions = scenario_cfg_lib.get_shmem_regions(ivshmem_region)
|
||||
if vm_id not in shmem_regions:
|
||||
continue
|
||||
|
||||
shmems = shmem_regions.get(vm_id)
|
||||
idx = 0
|
||||
for shm in shmems:
|
||||
if shm is None or shm.strip() == '':
|
||||
continue
|
||||
|
||||
shm_splited = shm.split(',')
|
||||
size = shm_splited[1].strip()
|
||||
try:
|
||||
int_size = int(size) * 0x100000
|
||||
except:
|
||||
int_size = 0
|
||||
if scenario_cfg_lib.VM_DB[vm_type]['load_type'] == "SOS_VM":
|
||||
# vbar[0] for shared memory is 4k
|
||||
free_bar0 = get_free_mmio(sos_mmio_range, mmiolist_per_vm[vm_id], BAR0_SHEMEM_ALIGNMENT + BAR0_SHEMEM_SIZE)
|
||||
free_bar0_start_addr = common.round_up(free_bar0.start, BAR0_SHEMEM_ALIGNMENT)
|
||||
free_bar0_end_addr = free_bar0_start_addr + BAR0_SHEMEM_SIZE - 1
|
||||
free_bar0 = MmioWindow(free_bar0_start_addr, free_bar0_end_addr)
|
||||
mmiolist_per_vm[vm_id].append(free_bar0)
|
||||
mmiolist_per_vm[vm_id].sort()
|
||||
# vbar[1] for shared memory is 4K
|
||||
free_bar1 = get_free_mmio(sos_mmio_range, mmiolist_per_vm[vm_id], BAR1_SHEMEM_ALIGNMENT + BAR1_SHEMEM_SIZE)
|
||||
free_bar1_start_addr = common.round_up(free_bar1.start, BAR1_SHEMEM_ALIGNMENT)
|
||||
free_bar1_end_addr = free_bar1_start_addr + BAR1_SHEMEM_SIZE - 1
|
||||
free_bar1 = MmioWindow(free_bar1_start_addr, free_bar1_end_addr)
|
||||
mmiolist_per_vm[vm_id].append(free_bar1)
|
||||
mmiolist_per_vm[vm_id].sort()
|
||||
# vbar[2] for shared memory is specified size in MB
|
||||
free_bar2 = get_free_mmio(sos_mmio_range, mmiolist_per_vm[vm_id], BAR2_SHEMEM_ALIGNMENT + int_size)
|
||||
free_bar2_start_addr = common.round_up(free_bar2.start, BAR2_SHEMEM_ALIGNMENT) + 0xC
|
||||
free_bar2_end_addr = free_bar2_start_addr + int_size - 1
|
||||
free_bar2 = MmioWindow(free_bar2_start_addr, free_bar2_end_addr)
|
||||
mmiolist_per_vm[vm_id].append(free_bar2)
|
||||
mmiolist_per_vm[vm_id].sort()
|
||||
print("#define SOS_IVSHMEM_DEVICE_%-19s" % (str(idx) + "_VBAR"),
|
||||
" .vbar_base[0] = {:#x}UL, \\".format(free_bar0.start), file=config)
|
||||
print("{}.vbar_base[1] = {:#x}UL, \\".format(' ' * 54, free_bar1.start), file=config)
|
||||
print("{}.vbar_base[2] = {:#x}UL".format(' ' * 54, free_bar2.start), file=config)
|
||||
print("", file=config)
|
||||
idx += 1
|
||||
elif scenario_cfg_lib.VM_DB[vm_type]['load_type'] == "PRE_LAUNCHED_VM":
|
||||
mmioRange = [MmioWindow(start=common.SIZE_2G, end=common.SIZE_4G-1)]
|
||||
# vbar[0] for shared memory is 4k
|
||||
free_bar0 = get_free_mmio(mmioRange, mmiolist_per_vm[vm_id], BAR0_SHEMEM_ALIGNMENT + BAR0_SHEMEM_SIZE)
|
||||
free_bar0_start_addr = common.round_up(free_bar0.start, BAR0_SHEMEM_ALIGNMENT)
|
||||
free_bar0_end_addr = free_bar0_start_addr + BAR0_SHEMEM_SIZE - 1
|
||||
free_bar0 = MmioWindow(free_bar0_start_addr, free_bar0_end_addr)
|
||||
mmiolist_per_vm[vm_id].append(free_bar0)
|
||||
mmiolist_per_vm[vm_id].sort()
|
||||
# vbar[1] for shared memory is 4K
|
||||
free_bar1 = get_free_mmio(mmioRange, mmiolist_per_vm[vm_id], BAR1_SHEMEM_ALIGNMENT + BAR1_SHEMEM_SIZE)
|
||||
free_bar1_start_addr = common.round_up(free_bar1.start, BAR1_SHEMEM_ALIGNMENT)
|
||||
free_bar1_end_addr = free_bar1_start_addr + BAR1_SHEMEM_SIZE - 1
|
||||
free_bar1 = MmioWindow(free_bar1_start_addr, free_bar1_end_addr)
|
||||
mmiolist_per_vm[vm_id].append(free_bar1)
|
||||
mmiolist_per_vm[vm_id].sort()
|
||||
# vbar[2] for shared memory is specified size in MB
|
||||
free_bar2 = get_free_mmio(mmioRange, mmiolist_per_vm[vm_id], BAR2_SHEMEM_ALIGNMENT + int_size)
|
||||
free_bar2_start_addr = common.round_up(free_bar2.start, BAR2_SHEMEM_ALIGNMENT) + 0xC
|
||||
free_bar2_end_addr = free_bar2_start_addr + int_size - 1
|
||||
free_bar2 = MmioWindow(free_bar2_start_addr, free_bar2_end_addr)
|
||||
mmiolist_per_vm[vm_id].append(free_bar2)
|
||||
mmiolist_per_vm[vm_id].sort()
|
||||
print("#define IVSHMEM_DEVICE_%-23s" % (str(idx) + "_VBAR"),
|
||||
" .vbar_base[0] = {:#x}UL, \\".format(free_bar0.start), file=config)
|
||||
print("{}.vbar_base[1] = {:#x}UL, \\".format(' ' * 54, free_bar1.start), file=config)
|
||||
print("{}.vbar_base[2] = {:#x}UL".format(' ' * 54, free_bar2.start), file=config)
|
||||
print("", file=config)
|
||||
idx += 1
|
||||
|
||||
|
||||
|
||||
def is_mmio_window_used(devinfo, keywords):
|
||||
for k in keywords:
|
||||
if k in devinfo:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_mmio_windows_with_key(keywords):
|
||||
keyword_mmiolist = []
|
||||
exclusive_mmiolist = []
|
||||
iomem_lines = board_cfg_lib.get_info(common.BOARD_INFO_FILE, "<IOMEM_INFO>", "</IOMEM_INFO>")
|
||||
|
||||
for line in iomem_lines:
|
||||
mmio_range = line.split(':')[0]
|
||||
devmmio_tuple = MmioWindow.from_str(mmio_range)
|
||||
if is_mmio_window_used(line, keywords):
|
||||
keyword_mmiolist.append(devmmio_tuple)
|
||||
else:
|
||||
exclusive_mmiolist.append(devmmio_tuple)
|
||||
return sorted(keyword_mmiolist), sorted(exclusive_mmiolist)
|
||||
|
||||
|
||||
def removed_nested(list1, list2):
|
||||
if not list1 or not list2:
|
||||
return list1
|
||||
|
||||
resolvedList = list1[:]
|
||||
for w1 in resolvedList:
|
||||
for w2 in list2:
|
||||
if w2.start <= w1.start <= w2.end and w2.start <= w1.end <= w2.end:
|
||||
if w1 not in resolvedList:
|
||||
continue
|
||||
resolvedList.remove(w1)
|
||||
return sorted(resolvedList)
|
||||
|
||||
|
||||
def merged_windows(windowslist):
|
||||
if not windowslist:
|
||||
return None
|
||||
|
||||
sortedlist = sorted(windowslist)
|
||||
resolvedList = []
|
||||
last = sortedlist[0]
|
||||
for cur in sortedlist:
|
||||
if cur.start <= last.end + 1:
|
||||
last = MmioWindow(start=last.start, end=max(last.end, cur.end))
|
||||
else:
|
||||
resolvedList.append(last)
|
||||
last = cur
|
||||
resolvedList.append(last)
|
||||
return sorted(resolvedList)
|
||||
|
||||
|
||||
def get_free_mmio(windowslist, used, size):
|
||||
if not size:
|
||||
raise ValueError("allocate size cannot be {}".format(size))
|
||||
if not windowslist:
|
||||
raise ValueError("No mmio range is specified:{}".format(windowslist))
|
||||
for w in windowslist:
|
||||
window = MmioWindow(start=w.start, end=w.start+size-1)
|
||||
for u in used:
|
||||
if window.overlaps(u):
|
||||
window = MmioWindow(start=u.end+1, end=u.end+size)
|
||||
continue
|
||||
if window.overlaps(w):
|
||||
return window
|
||||
raise ValueError("Not enough mmio window for a device size {}: {}".format(size, window))
|
||||
|
||||
|
||||
def generate_file(config):
|
||||
matching_mmios, non_matching_mmios = get_mmio_windows_with_key(['PCI Bus 0000:00'])
|
||||
matching_mmios = removed_nested(matching_mmios, non_matching_mmios)
|
||||
non_matching_mmios = [
|
||||
w for w in non_matching_mmios
|
||||
if any((w.overlaps(w2) for w2 in matching_mmios))
|
||||
]
|
||||
non_matching_mmios = merged_windows(non_matching_mmios)
|
||||
|
||||
# list of all vmsix supported device list in bdf format
|
||||
bdf_list = board_cfg_lib.get_known_caps_pci_devs().get('VMSIX', [])
|
||||
# list of all PRE_LAUNCHED_VMs' vmsix supported passthrough devices in bdf format
|
||||
pci_items = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "pci_devs", "pci_dev")
|
||||
pci_devs = scenario_cfg_lib.get_pt_pci_devs(pci_items)
|
||||
pci_devs_per_vm = get_devs_per_vm_with_key(pci_devs, bdf_list)
|
||||
# list SOS vmsix supported devices without other PRE_LAUNCHED_VMs' in bdf format
|
||||
sos_bdf_list = [
|
||||
d for d in bdf_list
|
||||
if all((d not in pci_devs_per_vm[i] for i in pci_devs_per_vm))
|
||||
]
|
||||
|
||||
for vm_i in pci_devs_per_vm:
|
||||
vm_type = common.VM_TYPES[vm_i]
|
||||
if scenario_cfg_lib.VM_DB[vm_type]['load_type'] == "SOS_VM":
|
||||
pci_devs_per_vm[vm_i] = sos_bdf_list
|
||||
|
||||
mmiolist_per_vm = {}
|
||||
for vm_i,vm_type in common.VM_TYPES.items():
|
||||
if vm_i not in mmiolist_per_vm.keys():
|
||||
mmiolist_per_vm[vm_i] = []
|
||||
if scenario_cfg_lib.VM_DB[vm_type]['load_type'] == "SOS_VM":
|
||||
mmiolist_per_vm[vm_i] = non_matching_mmios
|
||||
else:
|
||||
if vm_i in pci_devs.keys():
|
||||
match, _ = get_mmio_windows_with_key(pci_devs[vm_i])
|
||||
mmiolist_per_vm[vm_i] = match
|
||||
if scenario_cfg_lib.VM_DB[vm_type]['load_type'] == "PRE_LAUNCHED_VM":
|
||||
if vm_i not in mmiolist_per_vm.keys():
|
||||
mmiolist_per_vm[vm_i] = []
|
||||
# TSN reserved region
|
||||
mmiolist_per_vm[vm_i].append(MmioWindow(start = 0xffff0000 , end = 0xffffffff))
|
||||
# For the pre-launched vm, if the TPM is passtrough, this address is used
|
||||
if vm_i == 0 and board_cfg_lib.is_tpm_passthru():
|
||||
mmiolist_per_vm[vm_i].append(MmioWindow(start = 0xfed40000, end = 0xfed40000 + 0x5000 - 1))
|
||||
# For the pre-launched vm o ehl-crb-b, if the p2sb is passtrough, this address is used
|
||||
if board_cfg_lib.is_matched_board(('ehl-crb-b')):
|
||||
p2sb_start = board_cfg_lib.find_p2sb_bar_addr()
|
||||
mmiolist_per_vm[vm_i].append(MmioWindow(start = p2sb_start, end = p2sb_start + 0x1000000 - 1))
|
||||
mmiolist_per_vm[vm_i].sort()
|
||||
|
||||
# start to generate board_info.h
|
||||
print("{0}".format(board_cfg_lib.HEADER_LICENSE), file=config)
|
||||
print(VBAR_INFO_DEFINE, file=config)
|
||||
common.get_vm_types()
|
||||
pre_vm = False
|
||||
sos_vm = False
|
||||
for vm_type in common.VM_TYPES.values():
|
||||
if scenario_cfg_lib.VM_DB[vm_type]['load_type'] == "PRE_LAUNCHED_VM":
|
||||
pre_vm = True
|
||||
if scenario_cfg_lib.VM_DB[vm_type]['load_type'] == "SOS_VM":
|
||||
sos_vm = True
|
||||
|
||||
if not pre_vm and not sos_vm:
|
||||
print(VBAR_INFO_ENDIF, file=config)
|
||||
return
|
||||
|
||||
ivshmem_enabled = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "IVSHMEM", "IVSHMEM_ENABLED")
|
||||
if ivshmem_enabled == 'y':
|
||||
write_ivshmem_vbar(mmiolist_per_vm, matching_mmios, config)
|
||||
|
||||
# Get passthrough devices vbar bases
|
||||
compared_bdf = []
|
||||
for cnt_sub_name in board_cfg_lib.SUB_NAME_COUNT.keys():
|
||||
i_cnt = 0
|
||||
for bdf, bar_attr in board_cfg_lib.PCI_DEV_BAR_DESC.pci_dev_dic.items():
|
||||
if cnt_sub_name == bar_attr.name and bdf not in compared_bdf:
|
||||
compared_bdf.append(bdf)
|
||||
else:
|
||||
continue
|
||||
|
||||
write_vbar(i_cnt, bdf, board_cfg_lib.PCI_DEV_BAR_DESC.pci_bar_dic, bar_attr, \
|
||||
pci_devs_per_vm, mmiolist_per_vm, matching_mmios, config)
|
||||
|
||||
i_cnt += 1
|
||||
|
||||
write_vuart_vbar(mmiolist_per_vm, matching_mmios, config)
|
||||
print(VBAR_INFO_ENDIF, file=config)
|
Reference in New Issue
Block a user