1# Copyright (C) 2019-2022 Intel Corporation. 2# 3# SPDX-License-Identifier: BSD-3-Clause 4# 5 6import sys 7import enum 8import board_cfg_lib 9import acrn_config_utilities 10from defusedxml.lxml import parse 11import os 12from acrn_config_utilities import get_node 13 14class RDT(enum.Enum): 15 L2 = 0 16 L3 = 1 17 MBA = 2 18 19INCLUDE_HEADER = """ 20#include <asm/board.h> 21#include <asm/vtd.h> 22#include <asm/msr.h> 23#include <asm/rdt.h> 24#include <pci.h> 25#include <misc_cfg.h> 26""" 27 28MSR_IA32_L2_MASK_BASE = 0x00000D10 29MSR_IA32_L2_MASK_END = 0x00000D4F 30MSR_IA32_L3_MASK_BASE = 0x00000C90 31MSR_IA32_L3_MASK_END = 0x00000D0F 32 33 34def gen_dmar_structure(config): 35 """Generate dmar structure information""" 36 37 dmar_info_lines = board_cfg_lib.get_info(acrn_config_utilities.BOARD_INFO_FILE, "<DRHD_INFO>", "</DRHD_INFO>") 38 drhd_cnt = 0 39 drhd_dev_scope_cnt = [] 40 dev_scope_type = [] 41 42 if not dmar_info_lines: 43 print("\n#ifndef CONFIG_ACPI_PARSE_ENABLED", file=config) 44 print("#error \"DMAR info is not available, please set ACPI_PARSE_ENABLED to y. \\", file=config) 45 print("\tOr use acrn-config tool to generate platform DMAR info.\"", file=config) 46 print("#endif\n", file=config) 47 48 print("struct dmar_info plat_dmar_info;\n", file=config) 49 return 50 51 # parse to get DRHD count and dev scope count 52 for dmar_line in dmar_info_lines: 53 if "DRHD_COUNT" in dmar_line and not drhd_cnt: 54 drhd_cnt = int(dmar_line.split()[2].strip('U')) 55 56 for i_cnt in range(drhd_cnt): 57 for dmar_line in dmar_info_lines: 58 dev_scope_cnt_str = "DRHD{}_DEV_CNT".format(i_cnt) 59 60 if dev_scope_cnt_str in dmar_line: 61 tmp_dev_scope_cnt = int(dmar_line.split()[2].strip('U'), 16) 62 drhd_dev_scope_cnt.append(tmp_dev_scope_cnt) 63 64 # gen dmar structure information 65 for i_drhd_cnt in range(drhd_cnt): 66 dev_cnt = drhd_dev_scope_cnt[i_drhd_cnt] 67 print("static struct dmar_dev_scope drhd{}_dev_scope[DRHD{}_DEV_CNT] = {{".format( 68 i_drhd_cnt, i_drhd_cnt), file=config) 69 for i_dev_cnt in range(dev_cnt): 70 print("\t{", file=config) 71 print("\t\t.type = DRHD{}_DEVSCOPE{}_TYPE,".format(i_drhd_cnt, i_dev_cnt), file=config) 72 print("\t\t.id = DRHD{}_DEVSCOPE{}_ID,".format(i_drhd_cnt, i_dev_cnt), file=config) 73 print("\t\t.bus = DRHD{}_DEVSCOPE{}_BUS,".format(i_drhd_cnt, i_dev_cnt), file=config) 74 print("\t\t.devfun = DRHD{}_DEVSCOPE{}_PATH,".format(i_drhd_cnt, i_dev_cnt), file=config) 75 print("\t},", file=config) 76 77 print("};", file=config) 78 print("", file=config) 79 80 print("static struct dmar_drhd drhd_info_array[DRHD_COUNT] = {", file=config) 81 for i_drhd_cnt in range(drhd_cnt): 82 print("\t{", file=config) 83 print("\t\t.dev_cnt = DRHD{}_DEV_CNT,".format(i_drhd_cnt), file=config) 84 print("\t\t.segment = DRHD{}_SEGMENT,".format(i_drhd_cnt), file=config) 85 print("\t\t.flags = DRHD{}_FLAGS,".format(i_drhd_cnt), file=config) 86 print("\t\t.reg_base_addr = DRHD{}_REG_BASE,".format(i_drhd_cnt), file=config) 87 print("\t\t.ignore = DRHD{}_IGNORE,".format(i_drhd_cnt), file=config) 88 print("\t\t.devices = drhd{}_dev_scope".format(i_drhd_cnt), file=config) 89 print("\t},", file=config) 90 91 print("};", file=config) 92 print("", file=config) 93 print("struct dmar_info plat_dmar_info = {", file=config) 94 print("\t.drhd_count = DRHD_COUNT,", file=config) 95 print("\t.drhd_units = drhd_info_array,", file=config) 96 print("};", file=config) 97 98 99def populate_clos_mask_msr(rdt_res, cat_mask_list, config): 100 """ 101 Populate the clos bitmask and msr index for a given RDT resource 102 :param rdt_res: it is a string representing the RDT resource 103 :param cat_mask_list: cache mask list corresponding to each CLOS 104 :param config: it is a file pointer of board information for writing to 105 """ 106 idx = 0 107 for cat_mask in cat_mask_list: 108 print("\t{", file=config) 109 print("\t\t.clos_mask = {},".format(cat_mask), file=config) 110 print("\t},", file=config) 111 idx += 1 112 113def populate_mba_delay_mask(rdt_res, mba_delay_list, config): 114 """ 115 Populate the mba delay mask and msr index for memory resource 116 :param rdt_res: it is a string representing the RDT resource 117 :param mba_delay_list: mba delay value list corresponding to each CLOS 118 :param config: it is a file pointer of board information for writing to 119 """ 120 idx = 0 121 for mba_delay_mask in mba_delay_list: 122 print("\t{", file=config) 123 print("\t\t.mba_delay = ,".format(mba_delay_mask), file=config) 124 print("\t},", file=config) 125 idx += 1 126 127def get_rdt_enabled(): 128 scenario_etree = parse(acrn_config_utilities.SCENARIO_INFO_FILE) 129 enable = scenario_etree.xpath(f"//RDT_ENABLED/text()") 130 if enable[0] == "y": 131 return "true" 132 else: 133 return "false" 134 135def get_cdp_enabled(): 136 scenario_etree = parse(acrn_config_utilities.SCENARIO_INFO_FILE) 137 enable = scenario_etree.xpath(f"//CDP_ENABLED/text()") 138 if enable[0] == "y": 139 return "true" 140 else: 141 return "false" 142 143def get_common_clos_max(clos_number, capability_id): 144 145 common_clos_max = 0 146 if get_rdt_enabled() and not get_cdp_enabled(): 147 common_clos_max = clos_number 148 if get_cdp_enabled() and capability_id != 'MBA': 149 common_clos_max = clos_number / 2 150 151 return common_clos_max 152 153def gen_rdt_str(cache, config): 154 err_dic = {} 155 cat_mask_list = {} 156 157 board_etree = parse(acrn_config_utilities.BOARD_INFO_FILE) 158 mask_length = get_node(f"./capability[@id='CAT']/capacity_mask_length/text()", cache) 159 clos_number = get_node(f"./capability[@id='CAT']/clos_number/text()", cache) 160 161 bitmask = (1 << int(mask_length)) - 1 162 cache_level = get_node(f"./@level", cache) 163 cache_id = get_node(f"./@id", cache) 164 processor_list = board_etree.xpath(f"//cache[@level = '{cache_level}' and @id = '{cache_id}']/processors/processor/text()") 165 capability_list = board_etree.xpath(f"//cache[@level = '{cache_level}' and @id = '{cache_id}']/capability/@id") 166 167 for capability_id in capability_list: 168 169 common_clos_max = get_common_clos_max(int(clos_number), capability_id) 170 if capability_id == "CAT": 171 if common_clos_max > MSR_IA32_L2_MASK_END - MSR_IA32_L2_MASK_BASE or\ 172 common_clos_max > MSR_IA32_L3_MASK_END - MSR_IA32_L3_MASK_BASE: 173 err_dic["board config: Failed to generate board.c"] = "CLOS Mask Number is more then the reserved address region length of L2/L3 cache" 174 return err_dic 175 176 cdp_enable = get_cdp_enabled() 177 cat_mask_list = get_mask_list(cache_level, cache_id) 178 if len(cat_mask_list) > int(clos_number): 179 err_dic['board config: Failed to generate board.c'] = "CLOS Mask Number too bigger then the supported of L2/L3 cache" 180 return err_dic; 181 182 if cache_level == "2": 183 rdt_res = "l2" 184 elif cache_level == "3": 185 rdt_res = "l3" 186 187 clos_config_array = "platform_l{0}_clos_array_{1}".format(cache_level, int(cache_id, 16)) 188 189 print("\t{", file=config) 190 print("\t\t.res.cache = {", file=config) 191 print("\t\t\t.bitmask = {0},".format(hex(bitmask)), file=config) 192 print("\t\t\t.cbm_len = {0},".format(mask_length), file=config) 193 print("\t\t\t.is_cdp_enabled = {0},".format(cdp_enable), file=config) 194 print("\t\t},", file=config) 195 elif capability_id == "MBA": 196 max_throttling_value = get_node(f"./capability/max_throttling_value/text()", cache) 197 rdt_res = "mba" 198 clos_config_array = "platform_mba_clos_array" 199 print("\t{", file=config) 200 print("\t\t.res.membw = {", file=config) 201 print("\t\t\t.mba_max = {0},".format(clos_number), file=config) 202 print("\t\t\t.delay_linear = {0}".format(max_throttling_value), file=config) 203 print("\t\t},", file=config) 204 205 print("\t\t.num_closids = {0},".format(clos_number), file=config) 206 print("\t\t.num_clos_config = {0},".format(len(cat_mask_list)), file=config) 207 print("\t\t.clos_config_array = {0},".format(clos_config_array), file=config) 208 209 cpu_mask = 0 210 for processor in processor_list: 211 core_id = get_node(f"//thread[apic_id = '{processor}']/cpu_id/text()", board_etree) 212 if core_id is None: 213 continue 214 else: 215 cpu_mask = cpu_mask | (1 << int(core_id)) 216 print("\t\t.cpu_mask = {0},".format(hex(cpu_mask)), file=config) 217 print("\t},", file=config) 218 219 return err_dic; 220 221def get_mask_list(cache_level, cache_id): 222 allocation_dir = os.path.split(acrn_config_utilities.SCENARIO_INFO_FILE)[0] + "/configs/allocation.xml" 223 allocation_etree = parse(allocation_dir) 224 if cache_level == "3": 225 clos_list = allocation_etree.xpath(f"//clos_mask[@id = 'l3']/clos/text()") 226 else: 227 clos_list = allocation_etree.xpath(f"//clos_mask[@id = '{cache_id}']/clos/text()") 228 return clos_list 229def gen_clos_array(cache_list, config): 230 err_dic = {} 231 res_present = [0, 0, 0] 232 if len(cache_list) == 0: 233 print("union clos_config platform_{0}_clos_array[MAX_CACHE_CLOS_NUM_ENTRIES];".format("l2"), file=config) 234 print("union clos_config platform_{0}_clos_array[MAX_CACHE_CLOS_NUM_ENTRIES];".format("l3"), file=config) 235 print("union clos_config platform_{0}_clos_array[MAX_MBA_CLOS_NUM_ENTRIES];".format("mba"), file=config) 236 print("struct rdt_info res_infos[RDT_INFO_NUMBER];", file=config) 237 else: 238 for idx, cache in enumerate(cache_list): 239 cache_level = get_node(f"./@level", cache) 240 cache_id = get_node(f"./@id", cache) 241 clos_number = get_node(f"./capability/clos_number/text()", cache) 242 if cache_level == "2": 243 244 cat_mask_list = get_mask_list(cache_level, cache_id) 245 array_size = len(cat_mask_list) 246 247 print("union clos_config platform_l2_clos_array_{0}[{1}] = {{".format(int(cache_id, 16), clos_number), file=config) 248 249 populate_clos_mask_msr("L2", cat_mask_list, config) 250 251 print("};\n", file=config) 252 res_present[RDT.L2.value] += 1 253 elif cache_level == "3": 254 cat_mask_list = get_mask_list(cache_level, cache_id) 255 256 print("union clos_config platform_l3_clos_array_{0}[{1}] = {{".format(int(cache_id, 16), clos_number), file=config) 257 258 populate_clos_mask_msr("L3", cat_mask_list, config) 259 260 print("};\n", file=config) 261 res_present[RDT.L3.value] += 1 262 elif cache_level == "MBA": 263 print("union clos_config platform_mba_clos_array[MAX_MBA_CLOS_NUM_ENTRIES] = {", file=config) 264 err_dic = populate_mba_delay_mask("mba", mba_delay_list, config) 265 print("};\n", file=config) 266 res_present[RDT.MBA.value] = 1 267 else: 268 err_dic['board config: generate board.c failed'] = "The input of {} was corrupted!".format(acrn_config_utilities.BOARD_INFO_FILE) 269 return err_dic 270 271 if res_present[RDT.L2.value] == 0: 272 print("union clos_config platform_l2_clos_array[MAX_CACHE_CLOS_NUM_ENTRIES];", file=config) 273 if res_present[RDT.L3.value] == 0: 274 print("union clos_config platform_l3_clos_array[MAX_CACHE_CLOS_NUM_ENTRIES];", file=config) 275 if res_present[RDT.MBA.value] == 0: 276 print("union clos_config platform_mba_clos_array[MAX_MBA_CLOS_NUM_ENTRIES];", file=config) 277 return 0 278 279def gen_rdt_res(config): 280 """ 281 Get RDT resource (L2, L3, MBA) information 282 :param config: it is a file pointer of board information for writing to 283 """ 284 print("\n#ifdef CONFIG_RDT_ENABLED", file=config) 285 err_dic = {} 286 res_present = [0, 0, 0] 287 288 scenario_etree = parse(acrn_config_utilities.SCENARIO_INFO_FILE) 289 allocation_etree = parse(acrn_config_utilities.SCENARIO_INFO_FILE) 290 board_etree = parse(acrn_config_utilities.BOARD_INFO_FILE) 291 292 cache_list = board_etree.xpath(f"//cache[capability/@id = 'CAT' or capability/@id = 'MBA']") 293 gen_clos_array(cache_list, config) 294 295 cache_list = board_etree.xpath(f"//cache[capability/@id = 'CAT' and @level = '2']") 296 if len(cache_list) > 0: 297 res_present[RDT.L2.value] = len(cache_list) 298 rdt_ins_name = "rdt_ins_l2[" + str(len(cache_list)) + "] = {" 299 print("struct rdt_ins {}".format(rdt_ins_name), file=config) 300 for idx, cache in enumerate(cache_list): 301 err_dic = gen_rdt_str(cache, config) 302 if err_dic: 303 return err_dic; 304 print("};\n", file=config) 305 306 cache_list = board_etree.xpath(f"//cache[capability/@id = 'CAT' and @level = '3']") 307 if len(cache_list) > 0: 308 res_present[RDT.L3.value] = len(cache_list) 309 rdt_ins_name = "rdt_ins_l3[" + str(len(cache_list)) + "] = {" 310 print("struct rdt_ins {}".format(rdt_ins_name), file=config) 311 for idx, cache in enumerate(cache_list): 312 err_dic = gen_rdt_str(cache, config) 313 if err_dic: 314 return err_dic; 315 print("};\n", file=config) 316 317 cache_list = board_etree.xpath(f"//cache[capability/@id = 'MBA']") 318 if len(cache_list) > 0: 319 res_present[RDT.L2.value] = 1 320 rdt_ins_name = "rdt_ins_mba[" + str(len(cache_list)) + "] = {" 321 print("struct rdt_ins {}".format(rdt_ins_name), file=config) 322 for idx, cache in enumerate(cache_list): 323 err_dic = gen_rdt_str(cache, config) 324 if err_dic: 325 return err_dic; 326 print("};\n", file=config) 327 328 print("struct rdt_type res_cap_info[RDT_NUM_RESOURCES] = {", file=config) 329 if res_present[RDT.L2.value] > 0: 330 print("\t{", file=config) 331 print("\t\t.res_id = RDT_RESID_L2,", file=config) 332 print("\t\t.msr_qos_cfg = MSR_IA32_L2_QOS_CFG,", file=config) 333 print("\t\t.msr_base = MSR_IA32_L2_MASK_BASE,", file=config) 334 print("\t\t.num_ins = {},".format(res_present[RDT.L2.value]), file=config) 335 print("\t\t.ins_array = rdt_ins_l2,", file=config) 336 print("\t},", file=config) 337 if res_present[RDT.L3.value] > 0: 338 print("\t{", file=config) 339 print("\t\t.res_id = RDT_RESID_L3,", file=config) 340 print("\t\t.msr_qos_cfg = MSR_IA32_L3_QOS_CFG,", file=config) 341 print("\t\t.msr_base = MSR_IA32_L3_MASK_BASE,", file=config) 342 print("\t\t.num_ins = {},".format(res_present[RDT.L3.value]), file=config) 343 print("\t\t.ins_array = rdt_ins_l3,", file=config) 344 print("\t},", file=config) 345 if res_present[RDT.MBA.value] > 0: 346 print("\t{", file=config) 347 print("\t\t.res_id = RDT_RESID_MBA,", file=config) 348 print("\t\t.msr_qos_cfg = MSR_IA32_MBA_QOS_CFG,", file=config) 349 print("\t\t.msr_base = MSR_IA32_MBA_MASK_BASE,", file=config) 350 print("\t\t.num_ins = {},".format(res_present[RDT.MBA.value]), file=config) 351 print("\t\t.ins_array = rdt_ins_mba,", file=config) 352 print("\t},", file=config) 353 print("};\n", file=config) 354 355 print("#endif\n", file=config) 356 357 return err_dic 358 359def gen_single_data(data_lines, domain_str, config): 360 line_i = 0 361 data_statues = True 362 data_len = len(data_lines) 363 364 if data_len == 0: 365 return 366 367 for data_l in data_lines: 368 if line_i == 0: 369 if "not available" in data_l: 370 print(data_l.strip(), file=config) 371 print("static const struct acrn_{}state_data board_cpu_{}x[0];".format(domain_str, domain_str), file=config) 372 print("", file=config) 373 data_statues = False 374 break 375 else: 376 print("static const struct acrn_{}state_data board_cpu_{}x[{}] = {{".format(domain_str, domain_str, data_len), file=config) 377 print("\t{0}".format(data_l.strip()), file=config) 378 line_i += 1 379 if data_statues: 380 print("};\n", file=config) 381 382 383def gen_px_cx(config): 384 """ 385 Get Px/Cx and store them to board.c 386 :param config: it is a file pointer of board information for writing to 387 """ 388 cpu_brand_lines = board_cfg_lib.get_info( 389 acrn_config_utilities.BOARD_INFO_FILE, "<CPU_BRAND>", "</CPU_BRAND>") 390 cx_lines = board_cfg_lib.get_info(acrn_config_utilities.BOARD_INFO_FILE, "<CX_INFO>", "</CX_INFO>") 391 px_lines = board_cfg_lib.get_info(acrn_config_utilities.BOARD_INFO_FILE, "<PX_INFO>", "</PX_INFO>") 392 393 gen_single_data(cx_lines, 'c', config) 394 gen_single_data(px_lines, 'p', config) 395 396 if not cpu_brand_lines: 397 print("\nconst struct cpu_state_table board_cpu_state_tbl;\n", file=config) 398 return 399 400 for brand_line in cpu_brand_lines: 401 cpu_brand = brand_line 402 403 print("const struct cpu_state_table board_cpu_state_tbl = {", file=config) 404 print("\t{0},".format(cpu_brand.strip()), file=config) 405 print("\t{(uint8_t)ARRAY_SIZE(board_cpu_px), board_cpu_px,", file=config) 406 print("\t(uint8_t)ARRAY_SIZE(board_cpu_cx), board_cpu_cx}", file=config) 407 print("};", file=config) 408 409 410def gen_pci_hide(config): 411 """Generate hide pci information for this platform""" 412 413 scenario_etree = parse(acrn_config_utilities.SCENARIO_INFO_FILE) 414 hidden_pdev_list = [x.replace('.', ':') for x in scenario_etree.xpath(f"//HIDDEN_PDEV/text()")] 415 416 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: 417 hidden_pdev_list += board_cfg_lib.KNOWN_HIDDEN_PDEVS_BOARD_DB[board_cfg_lib.BOARD_NAME] 418 419 if len(hidden_pdev_list) > 0: 420 hidden_pdev_num = len(hidden_pdev_list) 421 print("const union pci_bdf plat_hidden_pdevs[MAX_HIDDEN_PDEVS_NUM] = {", file=config) 422 for hidden_pdev_i in range(hidden_pdev_num): 423 bus = hex(int(hidden_pdev_list[hidden_pdev_i].split(':')[0], 16)) 424 dev = hex(int(hidden_pdev_list[hidden_pdev_i].split(':')[1], 16)) 425 fun = hex(int(hidden_pdev_list[hidden_pdev_i].split(':')[2], 16)) 426 print("\t{", file=config) 427 print("\t\t.bits.b = {}U,".format(bus), file=config) 428 print("\t\t.bits.d = {}U,".format(dev), file=config) 429 print("\t\t.bits.f = {}U,".format(fun), file=config) 430 print("\t},", file=config) 431 print("};", file=config) 432 else: 433 print("const union pci_bdf plat_hidden_pdevs[MAX_HIDDEN_PDEVS_NUM];", file=config) 434 435 436def gen_known_caps_pci_devs(config): 437 """Generate information for known capabilities of pci devices""" 438 known_caps_pci_devs = board_cfg_lib.get_known_caps_pci_devs() 439 for dev,bdf_list in known_caps_pci_devs.items(): 440 if dev == "VMSIX": 441 print("", file=config) 442 bdf_list_len = len(bdf_list) 443 if bdf_list_len == 0: 444 print("const struct vmsix_on_msi_info vmsix_on_msi_devs[MAX_VMSIX_ON_MSI_PDEVS_NUM];", file=config) 445 break 446 for i in range(bdf_list_len): 447 b = bdf_list[i].split(":")[0] 448 d = bdf_list[i].split(":")[1].split(".")[0] 449 f = bdf_list[i].split(".")[1] 450 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) 451 452 for i in range(bdf_list_len): 453 if i == 0: 454 print("const struct vmsix_on_msi_info vmsix_on_msi_devs[MAX_VMSIX_ON_MSI_PDEVS_NUM] = {", file=config) 455 print("\t{{VMSIX_ON_MSI_DEV{}}},".format(i), file=config) 456 if i == (bdf_list_len - 1): 457 print("};", file=config) 458 459def gen_cpufreq_limits(config): 460 allocation_dir = os.path.split(acrn_config_utilities.SCENARIO_INFO_FILE)[0] + "/configs/allocation.xml" 461 allocation_etree = parse(allocation_dir) 462 cpu_list = board_cfg_lib.get_processor_info() 463 max_cpu_num = len(cpu_list) 464 465 print("\nstruct acrn_cpufreq_limits cpufreq_limits[MAX_PCPU_NUM] = {", file=config) 466 for cpu_id in range(max_cpu_num): 467 limit_node = get_node(f"//cpufreq/CPU[@id='{cpu_id}']/limits", allocation_etree) 468 if limit_node != None: 469 limit_guaranteed_lvl = get_node("./limit_guaranteed_lvl/text()", limit_node) 470 limit_highest_lvl = get_node("./limit_highest_lvl/text()", limit_node) 471 limit_lowest_lvl = get_node("./limit_lowest_lvl/text()", limit_node) 472 limit_nominal_pstate = get_node("./limit_nominal_pstate/text()", limit_node) 473 limit_highest_pstate = get_node("./limit_highest_pstate/text()", limit_node) 474 limit_lowest_pstate = get_node("./limit_lowest_pstate/text()", limit_node) 475 476 print("\t{", file=config) 477 print(f"\t\t.guaranteed_hwp_lvl = {limit_guaranteed_lvl},", file=config) 478 print(f"\t\t.highest_hwp_lvl = {limit_highest_lvl},", file=config) 479 print(f"\t\t.lowest_hwp_lvl = {limit_lowest_lvl},", file=config) 480 print(f"\t\t.nominal_pstate = {limit_nominal_pstate},", file=config) 481 print(f"\t\t.performance_pstate = {limit_highest_pstate},", file=config) 482 print("\t},", file=config) 483 print("};", file=config) 484 485def generate_file(config): 486 """ 487 Start to generate board.c 488 :param config: it is a file pointer of board information for writing to 489 """ 490 err_dic = {} 491 print("{0}".format(board_cfg_lib.HEADER_LICENSE), file=config) 492 493 # insert bios info into board.c 494 board_cfg_lib.handle_bios_info(config) 495 print(INCLUDE_HEADER, file=config) 496 497 # start to parse DMAR info 498 gen_dmar_structure(config) 499 500 # start to parse RDT resource info 501 err_dic = gen_rdt_res(config) 502 if err_dic: 503 return err_dic 504 505 # start to parse PX/CX info 506 gen_px_cx(config) 507 508 # gen hide pci info for platform 509 gen_pci_hide(config) 510 511 # gen known caps of pci dev info for platform 512 gen_known_caps_pci_devs(config) 513 514 gen_cpufreq_limits(config) 515 516 return err_dic 517