1# Copyright (C) 2019-2022 Intel Corporation. 2# 3# SPDX-License-Identifier: BSD-3-Clause 4# 5 6import re 7import sys 8import acrn_config_utilities 9import collections 10 11BOARD_NAME = '' 12BIOS_INFO = ['BIOS Information', 'Vendor:', 'Version:', 'Release Date:', 'BIOS Revision:'] 13BASE_BOARD = ['Base Board Information', 'Manufacturer:', 'Product Name:', 'Version:'] 14 15LEGACY_TTYS = { 16 'ttyS0':'0x3F8', 17 'ttyS1':'0x2F8', 18 'ttyS2':'0x3E8', 19 'ttyS3':'0x2E8', 20} 21 22VALID_LEGACY_IRQ = [] 23ERR_LIST = {} 24USED_RAM_RANGE = {} 25 26HEADER_LICENSE = acrn_config_utilities.open_license() + "\n" 27 28# The data base contains hide pci device 29KNOWN_HIDDEN_PDEVS_BOARD_DB = { 30 'apl-mrb':['00:0d:0'], 31 'apl-up2':['00:0d:0'], 32} 33 34TSN_DEVS = ["8086:4b30", "8086:4b31", "8086:4b32", "8086:4ba0", "8086:4ba1", "8086:4ba2", 35 "8086:4bb0", "8086:4bb1", "8086:4bb2", "8086:a0ac", "8086:43ac", "8086:43a2"] 36GPIO_DEVS = ["8086:4b88", "8086:4b89"] 37TPM_PASSTHRU_BOARD = ['whl-ipc-i5', 'whl-ipc-i7', 'tgl-rvp', 'ehl-crb-b', 'cfl-k700-i7'] 38 39KNOWN_CAPS_PCI_DEVS_DB = { 40 "VMSIX":TSN_DEVS + GPIO_DEVS, 41} 42 43P2SB_PASSTHRU_BOARD = ('ehl-crb-b') 44 45def get_info(board_info, msg_s, msg_e): 46 """ 47 Get information which specify by argument 48 :param board_info: it is a file what contains information for script to read from 49 :param msg_s: it is a pattern of key stings what start to match from board information 50 :param msg_e: it is a pattern of key stings what end to match from board information 51 """ 52 info_start = False 53 info_end = False 54 info_lines = [] 55 num = len(msg_s.split()) 56 57 with open(board_info, 'rt') as f_board: 58 while True: 59 60 line = f_board.readline() 61 if not line: 62 break 63 64 if " ".join(line.split()[0:num]) == msg_s: 65 info_start = True 66 info_end = False 67 continue 68 69 if " ".join(line.split()[0:num]) == msg_e: 70 info_start = False 71 info_end = True 72 continue 73 74 if info_start and not info_end: 75 info_lines.append(line) 76 continue 77 78 if not info_start and info_end: 79 return info_lines 80 81 82def handle_bios_info(config): 83 """ 84 Handle bios information 85 :param config: it is a file pointer of bios information for writing to 86 """ 87 bios_lines = get_info(acrn_config_utilities.BOARD_INFO_FILE, "<BIOS_INFO>", "</BIOS_INFO>") 88 board_lines = get_info(acrn_config_utilities.BOARD_INFO_FILE, "<BASE_BOARD_INFO>", "</BASE_BOARD_INFO>") 89 print("/*", file=config) 90 91 if not bios_lines or not board_lines: 92 print(" * DMI info is not found", file=config) 93 else: 94 i_cnt = 0 95 bios_board = BIOS_INFO + BASE_BOARD 96 97 # remove the same value and keep origin sort 98 bios_board_info = list(set(bios_board)) 99 bios_board_info.sort(key=bios_board.index) 100 101 bios_board_lines = bios_lines + board_lines 102 bios_info_len = len(bios_lines) 103 for line in bios_board_lines: 104 if i_cnt == bios_info_len: 105 print(" *", file=config) 106 107 i_cnt += 1 108 109 for misc_info in bios_board_info: 110 if misc_info == " ".join(line.split()[0:1]) or misc_info == \ 111 " ".join(line.split()[0:2]) or misc_info == " ".join(line.split()[0:3]): 112 print(" * {0}".format(line.strip()), file=config) 113 114 print(" */", file=config) 115 116 117def handle_root_dev(line): 118 """Handle if it match root device information pattern 119 :param line: one line of information which had decoded to 'ASCII' 120 """ 121 for root_type in line.split(): 122 # only support ext4 rootfs 123 if "ext4" in root_type: 124 return True 125 126 return False 127 128 129def get_max_clos_mask(board_file): 130 """ 131 Parse CLOS information 132 :param board_file: it is a file what contains board information for script to read from 133 :return: type of rdt resource supported and their corresponding clos max. 134 """ 135 rdt_res=[] 136 rdt_res_clos_max=[] 137 rdt_res_mask_max=[] 138 139 clos_lines = get_info(board_file, "<CLOS_INFO>", "</CLOS_INFO>") 140 for line in clos_lines: 141 if line.split(':')[0].strip() == "rdt resources supported": 142 rdt_res = line.split(':')[1].strip() 143 elif line.split(':')[0].strip() == "rdt resource clos max": 144 rdt_res_clos_max = line.split(':')[1].strip() 145 elif line.split(':')[0].strip() == "rdt resource mask max": 146 rdt_res_mask_max = line.split(':')[1].strip() 147 148 if (len(rdt_res) == 0) or (len(rdt_res_clos_max) == 0): 149 return rdt_res, rdt_res_clos_max, rdt_res_mask_max 150 else: 151 return list(re.split(r', |\s |,', rdt_res)), list(map(int, rdt_res_clos_max.split(','))), list(re.split(r', |\s |,', rdt_res_mask_max)) 152 153 154def get_rootfs(config_file): 155 """ 156 This will get rootfs partition from board information 157 :param config_file: it is a file which contain board information 158 :return: rootfs partition list 159 """ 160 root_dev_list = [] 161 rootfs_lines = get_info(config_file, "<BLOCK_DEVICE_INFO>", "</BLOCK_DEVICE_INFO>") 162 163 # none 'BLOCK_DEVICE_INFO' tag 164 if rootfs_lines == None: 165 return root_dev_list 166 167 for rootfs_line in rootfs_lines: 168 if not rootfs_line: 169 break 170 171 if not handle_root_dev(rootfs_line): 172 continue 173 174 root_dev = rootfs_line.strip().split(':')[0] 175 root_dev_list.append(root_dev) 176 177 return (root_dev_list, len(root_dev_list)) 178 179 180def clos_info_parser(board_info): 181 """ Parse CLOS information """ 182 return get_max_clos_mask(board_info) 183 184 185def get_valid_irq(board_info): 186 """ 187 This is get available irq from board info file 188 :param board_info: it is a file what contains board information for script to read from 189 :return: None 190 """ 191 global VALID_LEGACY_IRQ 192 val_irq = [] 193 irq_info_lines = get_info(board_info, "<AVAILABLE_IRQ_INFO>", "</AVAILABLE_IRQ_INFO>") 194 for irq_string in irq_info_lines: 195 val_irq = [x.strip() for x in irq_string.split(',')] 196 197 VALID_LEGACY_IRQ = val_irq 198 199 200def alloc_irq(): 201 """ 202 This is allocated an available irq 203 :return: free irq 204 """ 205 irq_val = VALID_LEGACY_IRQ.pop(0) 206 207 return irq_val 208 209 210def parser_hv_console(): 211 """ 212 There may be 3 types in the console item 213 1. BDF:(00:18.2) seri:/dev/ttyS2 214 2. /dev/ttyS2 215 3. ttyS2 216 """ 217 ttys_n = '' 218 err_dic = {} 219 ttys = acrn_config_utilities.get_hv_item_tag(acrn_config_utilities.SCENARIO_INFO_FILE, "DEBUG_OPTIONS", "SERIAL_CONSOLE") 220 221 if not ttys or ttys == None: 222 return (err_dic, ttys_n) 223 224 if ttys and 'BDF' in ttys or '/dev' in ttys: 225 ttys_n = ttys.split('/')[2] 226 else: 227 ttys_n = ttys 228 229 return (err_dic, ttys_n) 230 231 232def get_processor_info(): 233 """ 234 Get cpu processor list 235 :param board_info: it is a file what contains board information 236 :return: cpu processor list 237 """ 238 processor_list = [] 239 tmp_list = [] 240 processor_info = get_info(acrn_config_utilities.BOARD_INFO_FILE, "<CPU_PROCESSOR_INFO>", "</CPU_PROCESSOR_INFO>") 241 242 if not processor_info: 243 key = "CPU PROCESSOR_INFO error:" 244 ERR_LIST[key] = "CPU core is not exists" 245 return processor_list 246 247 for processor_line in processor_info: 248 if not processor_line: 249 break 250 251 processor_list = processor_line.strip().split(',') 252 for processor in processor_list: 253 tmp_list.append(processor.strip()) 254 break 255 256 return tmp_list 257 258 259def get_native_ttys_info(board_info): 260 """ 261 Get ttySn from board info 262 :param board_info: it is a file what contains board information for script to read from 263 :return: serial port list 264 """ 265 ttys_list = [] 266 ttys_info = get_info(board_info, "<TTYS_INFO>", "</TTYS_INFO>") 267 268 for ttys_line in ttys_info: 269 if not ttys_line: 270 break 271 272 ttys_dev = ttys_line.split()[0].split(':')[1] 273 ttysn = ttys_dev.split('/')[-1] 274 # currently Service VM OS console can only support legacy serial port 275 if ttysn not in list(LEGACY_TTYS.keys()): 276 continue 277 ttys_list.append(ttys_dev) 278 279 return ttys_list 280 281def get_total_mem(): 282 """ 283 get total memory size from config file which is dumped from native board 284 :return: integer number of total memory size, Unit: MByte 285 """ 286 scale_to_mb = 1 287 total_mem_mb = scale_to_mb 288 mem_lines = get_info(acrn_config_utilities.BOARD_INFO_FILE, "<TOTAL_MEM_INFO>", "</TOTAL_MEM_INFO>") 289 for mem_line in mem_lines: 290 mem_info_list = mem_line.split() 291 292 if len(mem_info_list) <= 1: 293 return total_mem_mb 294 295 if mem_info_list[1] == "kB": 296 scale_to_mb = 1024 297 298 total_mem_mb = int(mem_info_list[0]) / scale_to_mb 299 return total_mem_mb 300 301 302def get_pci_info(board_info): 303 pci_bdf_vpid = {} 304 pci_vid_start = False 305 pci_vid_end = False 306 pci_desc = {} 307 pci_start = False 308 pci_end = False 309 310 with open(board_info, 'r') as f: 311 while True: 312 line = f.readline() 313 if not line: 314 break 315 316 s = " " 317 if s.join(line.split()[0:2]) == "<PCI_DEVICE>": 318 pci_start = True 319 pci_end = False 320 continue 321 322 if s.join(line.split()[0:2]) == "</PCI_DEVICE>": 323 pci_start = False 324 pci_end = True 325 continue 326 327 # all pci device wiht description 328 if pci_start and not pci_end: 329 if "Region" in line and "Memory at" in line: 330 continue 331 bdf = line.split()[0] 332 pci_desc[bdf] = line 333 334 if s.join(line.split()[0:2]) == "<PCI_VID_PID>": 335 pci_vid_start = True 336 pci_vid_end = False 337 continue 338 339 if s.join(line.split()[0:2]) == "</PCI_VID_PID>": 340 pci_vid_start = False 341 pci_vid_end = True 342 continue 343 344 # all pci device with vid/pid and bdf 345 if pci_vid_start and not pci_vid_end: 346 bdf_str = line.split()[0] 347 vid_pid = line.split()[2] 348 pci_bdf_vpid[bdf_str] = vid_pid 349 350 return (pci_desc, pci_bdf_vpid) 351 352def get_p_state_count(): 353 """ 354 Get cpu p-state count 355 :return: p-state count 356 """ 357 px_info = get_info(acrn_config_utilities.BOARD_INFO_FILE, "<PX_INFO>", "</PX_INFO>") 358 if px_info != None: 359 for line in px_info: 360 if re.search("{.*}", line) == None: 361 px_info.remove(line) 362 363 return len(px_info) 364 365def get_p_state_index_from_ratio(ratio): 366 """ 367 Get the closest p-state index that is lesser than or equel to given ratio 368 :return: p-state index; If no px_info found in board file, return 0; 369 """ 370 closest_index = 0 371 px_info = get_info(acrn_config_utilities.BOARD_INFO_FILE, "<PX_INFO>", "</PX_INFO>") 372 if px_info != None: 373 for line in px_info: 374 if re.search("{.*}", line) == None: 375 px_info.remove(line) 376 377 i = 0 378 closest_index = 1 379 for line in px_info: 380 l = re.search(r"0x(\w*)UL}", line) 381 if l != None: 382 state_ratio = int(l.group(1), 16) >> 8 383 if state_ratio <= ratio: 384 closest_index = i 385 break 386 i += 1 387 388 return closest_index 389 390HI_MMIO_OFFSET = 0 391 392class Bar_Mem: 393 def __init__(self): 394 self.addr = 0 395 self.remapped = False 396 397 398class Bar_Attr: 399 def __init__(self): 400 self.name = 0 401 self.remappable = True 402 self.name_w_i_cnt = 0 403 404class Pci_Dev_Bar_Desc: 405 def __init__(self): 406 self.pci_dev_dic = collections.OrderedDict() 407 self.pci_bar_dic = collections.OrderedDict() 408 self.shm_bar_dic = collections.OrderedDict() 409 410PCI_DEV_BAR_DESC = Pci_Dev_Bar_Desc() 411SUB_NAME_COUNT = collections.OrderedDict() 412 413 414def get_value_after_str(line, key): 415 """ Get the value after cstate string """ 416 idx = 0 417 line_in_list = line.split() 418 for idx_key, val in enumerate(line_in_list): 419 if val == key: 420 idx = idx_key 421 break 422 423 return line_in_list[idx + 1] 424 425 426def check_bar_remappable(line): 427 #TODO: check device BAR remappable per ACPI table 428 429 return True 430 431 432def get_size(line): 433 434 # get size string from format, Region n: Memory at x ... [size=NK] 435 size_str = line.split()[-1].strip(']').split('=')[1] 436 if 'G' in size_str: 437 size = int(size_str.strip('G')) * acrn_config_utilities.SIZE_G 438 elif 'M' in size_str: 439 size = int(size_str.strip('M')) * acrn_config_utilities.SIZE_M 440 elif 'K' in size_str: 441 size = int(size_str.strip('K')) * acrn_config_utilities.SIZE_K 442 else: 443 size = int(size_str) 444 445 return size 446 447# round up the running bar_addr to the size of the incoming bar "line" 448def remap_bar_addr_to_high(bar_addr, line): 449 """Generate vbar address""" 450 global HI_MMIO_OFFSET 451 size = get_size(line) 452 cur_addr = acrn_config_utilities.round_up(bar_addr, size) 453 HI_MMIO_OFFSET = cur_addr + size 454 return cur_addr 455 456 457def parser_pci(): 458 """ Parse PCI lines """ 459 global SUB_NAME_COUNT, HI_MMIO_OFFSET 460 cur_bdf = 0 461 prev_bdf = 0 462 tmp_bar_dic = {} 463 bar_addr = bar_num = '0' 464 cal_sub_pci_name = [] 465 466 pci_lines = get_info(acrn_config_utilities.BOARD_INFO_FILE, "<PCI_DEVICE>", "</PCI_DEVICE>") 467 468 for line in pci_lines: 469 tmp_bar_mem = Bar_Mem() 470 # get pci bar information into board_cfg_lib.PCI_DEV_BAR_DESC 471 if "Region" in line and "Memory at" in line: 472 #ignore memory region from SR-IOV capabilities 473 if "size=" not in line: 474 continue 475 476 try: 477 bar_addr = int(get_value_after_str(line, "at"), 16) 478 except ValueError: 479 continue 480 481 bar_num = line.split()[1].strip(':') 482 if bar_addr >= acrn_config_utilities.SIZE_4G or bar_addr < acrn_config_utilities.SIZE_2G: 483 if not tmp_bar_attr.remappable: 484 continue 485 486 bar_addr = remap_bar_addr_to_high(HI_MMIO_OFFSET, line) 487 tmp_bar_mem.remapped = True 488 489 tmp_bar_mem.addr = hex(bar_addr) 490 tmp_bar_dic[int(bar_num)] = tmp_bar_mem 491 else: 492 tmp_bar_attr = Bar_Attr() 493 prev_bdf = cur_bdf 494 pci_bdf = line.split()[0] 495 tmp_bar_attr.name = " ".join(line.split(':')[1].split()[1:]) 496 497 # remove '[*]' in pci subname 498 if '[' in tmp_bar_attr.name: 499 tmp_bar_attr.name = tmp_bar_attr.name.rsplit('[', 1)[0] 500 501 cal_sub_pci_name.append(tmp_bar_attr.name) 502 tmp_bar_attr.remappable = check_bar_remappable(line) 503 PCI_DEV_BAR_DESC.pci_dev_dic[pci_bdf] = tmp_bar_attr 504 cur_bdf = pci_bdf 505 506 if not prev_bdf: 507 prev_bdf = cur_bdf 508 509 if tmp_bar_dic and cur_bdf != prev_bdf: 510 PCI_DEV_BAR_DESC.pci_bar_dic[prev_bdf] = tmp_bar_dic 511 512 # clear the tmp_bar_dic before store the next dic 513 tmp_bar_dic = {} 514 515 # output all the pci device list to pci_device.h 516 for item in cal_sub_pci_name: 517 SUB_NAME_COUNT[item] = SUB_NAME_COUNT.get(item, 0) + 1 518 519 if tmp_bar_dic: 520 PCI_DEV_BAR_DESC.pci_bar_dic[cur_bdf] = tmp_bar_dic 521 522 523def parse_mem(): 524 raw_shmem_regions = acrn_config_utilities.get_hv_item_tag(acrn_config_utilities.SCENARIO_INFO_FILE, "FEATURES", "IVSHMEM", "IVSHMEM_REGION") 525 526 global USED_RAM_RANGE 527 for shm_name, shm_bar_dic in PCI_DEV_BAR_DESC.shm_bar_dic.items(): 528 if 0 in shm_bar_dic.keys() and int(shm_bar_dic[0].addr, 16) in USED_RAM_RANGE.keys(): 529 del USED_RAM_RANGE[int(shm_bar_dic[0].addr, 16)] 530 if 2 in shm_bar_dic.keys() and int(shm_bar_dic[2].addr, 16)-0xC in USED_RAM_RANGE.keys(): 531 del USED_RAM_RANGE[int(shm_bar_dic[2].addr, 16)-0xC] 532 533 idx = 0 534 for shm in raw_shmem_regions: 535 if shm is None or shm.strip() == '': 536 continue 537 shm_splited = shm.split(',') 538 name = shm_splited[0].strip() 539 size = shm_splited[1].strip() 540 541 try: 542 int_size = int(size) * 0x100000 543 except: 544 int_size = 0 545 ram_range = get_ram_range() 546 tmp_bar_dict = {} 547 hv_start_offset = 0x80000000 548 ret_start_addr = find_avl_memory(ram_range, str(0x200100), hv_start_offset) 549 bar_mem_0 = Bar_Mem() 550 bar_mem_0.addr = hex(acrn_config_utilities.round_up(int(ret_start_addr, 16), 0x200000)) 551 USED_RAM_RANGE[int(bar_mem_0.addr, 16)] = 0x100 552 tmp_bar_dict[0] = bar_mem_0 553 ram_range = get_ram_range() 554 hv_start_offset2 = 0x100000000 555 ret_start_addr2 = find_avl_memory(ram_range, str(int_size + 0x200000), hv_start_offset2) 556 bar_mem_2 = Bar_Mem() 557 bar_mem_2.addr = hex(acrn_config_utilities.round_up(int(ret_start_addr2, 16), 0x200000) + 0xC) 558 USED_RAM_RANGE[acrn_config_utilities.round_up(int(ret_start_addr2, 16), 0x20000)] = int_size 559 tmp_bar_dict[2] = bar_mem_2 560 PCI_DEV_BAR_DESC.shm_bar_dic[str(idx)+'_'+name] = tmp_bar_dict 561 idx += 1 562 563 564def is_rdt_supported(): 565 """ 566 Returns True if platform supports RDT else False 567 """ 568 (rdt_resources, rdt_res_clos_max, _) = clos_info_parser(acrn_config_utilities.BOARD_INFO_FILE) 569 if len(rdt_resources) == 0 or len(rdt_res_clos_max) == 0: 570 return False 571 else: 572 return True 573 574 575def is_rdt_enabled(): 576 """ 577 Returns True if RDT enabled else False 578 """ 579 rdt_enabled = acrn_config_utilities.get_hv_item_tag(acrn_config_utilities.SCENARIO_INFO_FILE, "FEATURES", "RDT", "RDT_ENABLED") 580 if is_rdt_supported() and rdt_enabled == 'y': 581 return True 582 return False 583 584 585def is_cdp_enabled(): 586 """ 587 Returns True if platform supports RDT/CDP else False 588 """ 589 rdt_enabled = is_rdt_enabled() 590 cdp_enabled = acrn_config_utilities.get_hv_item_tag(acrn_config_utilities.SCENARIO_INFO_FILE, "FEATURES", "RDT", "CDP_ENABLED") 591 if rdt_enabled and cdp_enabled == 'y': 592 return True 593 594 return False 595 596 597def get_rdt_select_opt(): 598 599 support_sel = ['n'] 600 if is_rdt_supported(): 601 support_sel.append('y') 602 return support_sel 603 604 605def get_common_clos_max(): 606 607 common_clos_max = 0 608 (res_info, rdt_res_clos_max, clos_max_mask_list) = clos_info_parser(acrn_config_utilities.BOARD_INFO_FILE) 609 if is_rdt_enabled() and not is_cdp_enabled(): 610 common_clos_max = min(rdt_res_clos_max) 611 612 if is_cdp_enabled(): 613 tmp_clos_max_list = [] 614 for res, clos_max in zip(res_info, rdt_res_clos_max): 615 if res == 'MBA': 616 tmp_clos_max_list.append(clos_max) 617 else: 618 tmp_clos_max_list.append(clos_max//2) 619 common_clos_max = min(tmp_clos_max_list) 620 621 return common_clos_max 622 623 624def get_sub_pci_name(i_cnt, bar_attr): 625 tmp_sub_name = '' 626 # if there is only one host bridge, then will discard the index of suffix 627 if i_cnt == 0 and bar_attr.name.upper() == "HOST BRIDGE": 628 tmp_sub_name = "_".join(bar_attr.name.split()).upper() 629 else: 630 if '-' in bar_attr.name: 631 tmp_sub_name = acrn_config_utilities.undline_name(bar_attr.name) + "_" + str(i_cnt) 632 else: 633 tmp_sub_name = "_".join(bar_attr.name.split()).upper() + "_" + str(i_cnt) 634 635 return tmp_sub_name 636 637def get_known_caps_pci_devs(): 638 known_caps_pci_devs = {} 639 vpid_lines = get_info(acrn_config_utilities.BOARD_INFO_FILE, "<PCI_VID_PID>", "</PCI_VID_PID>") 640 for dev,known_dev in KNOWN_CAPS_PCI_DEVS_DB.items(): 641 if dev not in known_caps_pci_devs: 642 known_caps_pci_devs[dev] = [] 643 for k_dev in known_dev: 644 for vpid_line in vpid_lines: 645 if k_dev in vpid_line: 646 bdf = vpid_line.split()[0] 647 known_caps_pci_devs[dev].append(bdf) 648 break 649 650 return known_caps_pci_devs 651 652 653def is_tpm_passthru(): 654 655 tpm_passthru = False 656 (_, board) = acrn_config_utilities.get_board_name() 657 tpm2_passthru_enabled = acrn_config_utilities.get_leaf_tag_map(acrn_config_utilities.SCENARIO_INFO_FILE, "mmio_resources", "TPM2") 658 if board in TPM_PASSTHRU_BOARD and tpm2_passthru_enabled and 'y' in tpm2_passthru_enabled.values(): 659 tpm_passthru = True 660 661 return tpm_passthru 662 663 664def find_avl_memory(ram_range, hpa_size, hv_start_offset): 665 """ 666 This is get hv address from System RAM as host physical size 667 :param ram_range: System RAM mapping 668 :param hpa_size: fixed host physical size 669 :param hv_start_offset: base address of HV RAM start 670 :return: start host physical address 671 """ 672 ret_start_addr = 0 673 tmp_order_key = 0 674 int_hpa_size = int(hpa_size, 10) 675 676 tmp_order_key = sorted(ram_range) 677 for start_addr in tmp_order_key: 678 mem_range = ram_range[start_addr] 679 if start_addr <= hv_start_offset and hv_start_offset + int_hpa_size <= start_addr + mem_range: 680 ret_start_addr = hv_start_offset 681 break 682 elif start_addr >= hv_start_offset and mem_range >= int_hpa_size: 683 ret_start_addr = start_addr 684 break 685 686 return hex(ret_start_addr) 687 688 689def get_ram_range(): 690 """ Get System RAM range mapping """ 691 # read system ram from board_info.xml 692 ram_range = {} 693 694 io_mem_lines = get_info( 695 acrn_config_utilities.BOARD_INFO_FILE, "<IOMEM_INFO>", "</IOMEM_INFO>") 696 697 for line in io_mem_lines: 698 if 'System RAM' not in line: 699 continue 700 start_addr = int(line.split('-')[0], 16) 701 end_addr = int(line.split('-')[1].split(':')[0], 16) 702 mem_range = end_addr - start_addr 703 ram_range[start_addr] = mem_range 704 705 global USED_RAM_RANGE 706 tmp_order_key_used = sorted(USED_RAM_RANGE) 707 for start_addr_used in tmp_order_key_used: 708 mem_range_used = USED_RAM_RANGE[start_addr_used] 709 tmp_order_key = sorted(ram_range) 710 for start_addr in tmp_order_key: 711 mem_range = ram_range[start_addr] 712 if start_addr < start_addr_used and start_addr_used + mem_range_used < start_addr + mem_range: 713 ram_range[start_addr] = start_addr_used - start_addr 714 ram_range[start_addr_used+mem_range_used] = start_addr + mem_range - start_addr_used - mem_range_used 715 break 716 elif start_addr == start_addr_used and start_addr_used + mem_range_used < start_addr + mem_range: 717 del ram_range[start_addr] 718 ram_range[start_addr_used + mem_range_used] = start_addr + mem_range - start_addr_used - mem_range_used 719 break 720 elif start_addr < start_addr_used and start_addr_used + mem_range_used == start_addr + mem_range: 721 ram_range[start_addr] = start_addr_used - start_addr 722 break 723 elif start_addr == start_addr_used and start_addr_used + mem_range_used == start_addr + mem_range: 724 del ram_range[start_addr] 725 break 726 else: 727 continue 728 729 return ram_range 730 731 732def is_p2sb_passthru_possible(): 733 734 p2sb_passthru = False 735 (_, board) = acrn_config_utilities.get_board_name() 736 if board in P2SB_PASSTHRU_BOARD: 737 p2sb_passthru = True 738 739 return p2sb_passthru 740 741 742def is_matched_board(boardlist): 743 744 (_, board) = acrn_config_utilities.get_board_name() 745 746 return board in boardlist 747 748 749def find_p2sb_bar_addr(): 750 if not is_matched_board(('ehl-crb-b')): 751 acrn_config_utilities.print_red('find_p2sb_bar_addr() can only be called for board ehl-crb-b', err=True) 752 sys.exit(1) 753 754 iomem_lines = get_info(acrn_config_utilities.BOARD_INFO_FILE, "<IOMEM_INFO>", "</IOMEM_INFO>") 755 756 for line in iomem_lines: 757 if 'INTC1020:' in line: 758 start_addr = int(line.split('-')[0], 16) & 0xFF000000 759 return start_addr 760 761 acrn_config_utilities.print_red('p2sb device is not found in board file %s!\n' % acrn_config_utilities.BOARD_INFO_FILE, err=True) 762 sys.exit(1) 763