1#!/usr/bin/env python3 2# 3# Copyright (C) 2021-2022 Intel Corporation. 4# 5# SPDX-License-Identifier: BSD-3-Clause 6# 7 8 9import sys, os, re 10sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'library')) 11import acrn_config_utilities, board_cfg_lib 12from collections import namedtuple 13from acrn_config_utilities import get_node 14 15PRE_LAUNCHED_VMS_TYPE = ["SAFETY_VM", "PRE_RT_VM", "PRE_STD_VM"] 16POST_LAUNCHED_VMS_TYPE = ["POST_STD_VM", "POST_RT_VM"] 17SERVICE_VM_TYPE = ["SERVICE_VM"] 18 19class BusDevFunc(namedtuple( 20 "BusDevFunc", [ 21 "bus", 22 "dev", 23 "func"])): 24 25 PATTERN = re.compile(r"(?P<bus>[0-9a-f]{2}):(?P<dev>[0-9a-f]{2})\.(?P<func>[0-7]{1})") 26 27 @classmethod 28 def from_str(cls, value): 29 if not(isinstance(value, str)): 30 raise ValueError("value must be a str: {}".format(type(value))) 31 32 match = cls.PATTERN.fullmatch(value) 33 if match: 34 return BusDevFunc( 35 bus=int(match.group("bus"), 16), 36 dev=int(match.group("dev"), 16), 37 func=int(match.group("func"), 16)) 38 else: 39 raise ValueError("not a bdf: {!r}".format(value)) 40 41 def __init__(self, *args, **kwargs): 42 if not (0x00 <= self.bus <= 0xff): 43 raise ValueError(f"Invalid bus number (0x00 ~ 0xff): {self.bus:#04x}") 44 if not (0x00 <= self.dev <= 0x1f): 45 raise ValueError(f"Invalid device number (0x00 ~ 0x1f): {self.dev:#04x}") 46 if not (0x0 <= self.func <= 0x7): 47 raise ValueError(f"Invalid function number (0 ~ 7): {self.func:#x}") 48 49 def __str__(self): 50 return f"PTDEV_{self.bus:02x}:{self.dev:02x}.{self.func:x}" 51 52 def __repr__(self): 53 return "BusDevFunc.from_str({!r})".format(str(self)) 54 55def parse_hv_console(scenario_etree): 56 """ 57 There may be 4 types in the console item 58 1. BDF:(00:18.2) seri:/dev/ttyS2 59 2. /dev/ttyS2 60 3. ttyS2 61 4. "None" 62 """ 63 ttys_n = '' 64 ttys = get_node("//SERIAL_CONSOLE/text()", scenario_etree) 65 66 if not ttys or ttys == None or ttys == 'None': 67 return ttys_n 68 69 if ttys and 'BDF' in ttys or '/dev' in ttys: 70 ttys_n = ttys.split('/')[2] 71 else: 72 ttys_n = ttys 73 74 return ttys_n 75 76def get_native_ttys(): 77 native_ttys = {} 78 ttys_lines = board_cfg_lib.get_info(acrn_config_utilities.BOARD_INFO_FILE, "<TTYS_INFO>", "</TTYS_INFO>") 79 if ttys_lines: 80 for tty_line in ttys_lines: 81 tmp_dic = {} 82 #seri:/dev/ttySx type:mmio base:0x91526000 irq:4 [bdf:"00:18.0"] 83 #seri:/dev/ttySy type:portio base:0x2f8 irq:5 84 tty = tty_line.split('/')[2].split()[0] 85 ttys_type = tty_line.split()[1].split(':')[1].strip() 86 ttys_base = tty_line.split()[2].split(':')[1].strip() 87 ttys_irq = tty_line.split()[3].split(':')[1].strip() 88 tmp_dic['type'] = ttys_type 89 tmp_dic['base'] = ttys_base 90 tmp_dic['irq'] = int(ttys_irq) 91 native_ttys[tty] = tmp_dic 92 return native_ttys 93 94def get_ivshmem_regions_by_tree(etree): 95 ivshmem_enabled = get_ivshmem_enabled_by_tree(etree) 96 if ivshmem_enabled == 'n': 97 return {} 98 99 ivshmem_regions = etree.xpath("//IVSHMEM_REGION") 100 shmem_regions = {} 101 for idx in range(len(ivshmem_regions)): 102 provided_by = get_node("./PROVIDED_BY/text()", ivshmem_regions[idx]) 103 if provided_by != "Hypervisor": 104 continue 105 shm_name = get_node("./NAME/text()", ivshmem_regions[idx]) 106 if shm_name is None: 107 continue 108 shm_size = get_node("./IVSHMEM_SIZE/text()", ivshmem_regions[idx]) 109 shm_vm_list = ivshmem_regions[idx].xpath(".//IVSHMEM_VM") 110 for shm_vm in shm_vm_list: 111 vm_name = get_node("./VM_NAME/text()", shm_vm) 112 vm_id = get_node(f"//vm[name = '{vm_name}']/@id", etree) 113 vbdf = get_node("./VBDF/text()", shm_vm) 114 if vm_id not in shmem_regions: 115 shmem_regions[vm_id] = {} 116 shmem_regions[vm_id][shm_name] = {'id' : str(idx), 'size' : shm_size, 'vbdf' : vbdf} 117 return shmem_regions 118 119def get_ivshmem_enabled_by_tree(etree): 120 ivshmem_vms = etree.xpath("//IVSHMEM_VM") 121 shmem_enabled = 'n' 122 if len(ivshmem_vms) != 0: 123 shmem_enabled = 'y' 124 return shmem_enabled 125 126def is_pre_launched_vm(vm_type): 127 if vm_type == 'PRE_LAUNCHED_VM': 128 return True 129 return False 130 131def is_post_launched_vm(vm_type): 132 if vm_type == 'POST_LAUNCHED_VM': 133 return True 134 return False 135 136def is_service_vm(vm_type): 137 if vm_type == 'SERVICE_VM': 138 return True 139 return False 140