mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-18 11:47:30 +00:00
Currently, MMIO PCI BDF of ttyS was indexed by IRQ, but it may found the wrong BDF when the IRQ was shared and it is not expected. So, the patch uses the MMIO base to query /proc/iomem to find BDF, the waring will get if BDF is not present in iomem. Tracked-On: #4862 Signed-off-by: Wei Liu <weix.w.liu@intel.com> Acked-by: Victor Sun <victor.sun@intel.com>
238 lines
6.4 KiB
Python
238 lines
6.4 KiB
Python
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
|
#
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
|
|
import parser_lib
|
|
import subprocess
|
|
|
|
MEM_PATH = ['/proc/iomem', '/proc/meminfo']
|
|
TTY_PATH = '/sys/class/tty/'
|
|
SYS_IRQ_PATH = '/proc/interrupts'
|
|
CPU_INFO_PATH = '/sys/devices/system/cpu/possible'
|
|
|
|
# Please refer kernel_src/include/linux/serial_core.h
|
|
ttys_type = {
|
|
'0': 'PORT', # 8b I/O port access
|
|
'2': 'MMIO', # driver-specific
|
|
'3': 'MMIO', # 32b little endian
|
|
'6': 'MMIO', # 32b big endian
|
|
}
|
|
|
|
|
|
ttys_irqs = []
|
|
|
|
|
|
def read_ttys_node(path):
|
|
with open(path, 'rt') as info:
|
|
ret_value = info.readline().strip()
|
|
|
|
return ret_value
|
|
|
|
|
|
def detected_ttys():
|
|
ttys_cnt = 8
|
|
tty_used_list = []
|
|
for s_inc in range(ttys_cnt):
|
|
cmd = 'stty -F /dev/ttyS{}'.format(s_inc)
|
|
res = parser_lib.cmd_execute('{}'.format(cmd))
|
|
|
|
while True:
|
|
line = res.stdout.readline().decode('ascii')
|
|
|
|
line_len = len(line.split())
|
|
if not line_len or line.split()[-1] == 'error':
|
|
break
|
|
|
|
ttys_n = "/dev/ttyS{}".format(s_inc)
|
|
tty_used_list.append(ttys_n)
|
|
break
|
|
|
|
return tty_used_list
|
|
|
|
|
|
def is_bdf_format(bdf):
|
|
is_bdf = False
|
|
|
|
if len(bdf) == 7 and len(bdf.split(':')[0]) == 2 and len(bdf.split(':')[1].split('.')[0]) == 2 and len(bdf.split(".")[1]) == 1:
|
|
is_bdf = True
|
|
|
|
return is_bdf
|
|
|
|
|
|
def iomem2bdf(base):
|
|
bdf = ''
|
|
base_iomem = base.strip('0x').lower()
|
|
with open(MEM_PATH[0], 'rt') as mem_info:
|
|
|
|
while True:
|
|
line = mem_info.readline().strip('\n')
|
|
if not line:
|
|
break
|
|
|
|
if base_iomem in line and '0000:' in line:
|
|
bdf = line.split(" ")[-1].lstrip("0000").lstrip(":")
|
|
if not is_bdf_format(bdf):
|
|
continue
|
|
else:
|
|
break
|
|
|
|
return bdf
|
|
|
|
def dump_ttys_info(ttys_list, config):
|
|
for ttys in ttys_list:
|
|
ttys_n = ttys.split('/')[-1]
|
|
type_path = '{}{}/io_type'.format(TTY_PATH, ttys_n)
|
|
serial_type = read_ttys_node(type_path)
|
|
|
|
irq_path = '{}{}/irq'.format(TTY_PATH, ttys_n)
|
|
irq = read_ttys_node(irq_path)
|
|
ttys_irqs.append(irq)
|
|
|
|
if ttys_type[serial_type] == 'PORT':
|
|
base_path = '{}{}/port'.format(TTY_PATH, ttys_n)
|
|
base = read_ttys_node(base_path)
|
|
print("\tseri:{} type:portio base:{} irq:{}".format(ttys, base, irq), file=config)
|
|
elif ttys_type[serial_type] == 'MMIO':
|
|
base_path = '{}{}/iomem_base'.format(TTY_PATH, ttys_n)
|
|
base = read_ttys_node(base_path)
|
|
bdf = iomem2bdf(base)
|
|
if bdf:
|
|
print('\tseri:{} type:mmio base:{} irq:{} bdf:"{}"'.format(ttys, base, irq, bdf), file=config)
|
|
else:
|
|
print('\tseri:{} type:mmio base:{} irq:{}'.format(ttys, base, irq), file=config)
|
|
|
|
|
|
def dump_ttys(config):
|
|
"""This will get systemd ram which are usable
|
|
:param config: file pointer that opened for writing board config information
|
|
"""
|
|
print("\t<TTYS_INFO>", file=config)
|
|
ttys_list = detected_ttys()
|
|
|
|
dump_ttys_info(ttys_list, config)
|
|
|
|
print("\t</TTYS_INFO>", file=config)
|
|
print("", file=config)
|
|
|
|
|
|
def dump_free_irqs(config):
|
|
irq_list = ['3', '4', '5', '6', '7', '8', '10', '11', '12', '13', '14', '15']
|
|
for tty_irq in ttys_irqs:
|
|
if tty_irq in irq_list:
|
|
irq_list.remove(tty_irq)
|
|
|
|
print("\t<AVAILABLE_IRQ_INFO>", file=config)
|
|
with open(SYS_IRQ_PATH, 'rt') as irq_config:
|
|
|
|
while True:
|
|
line = irq_config.readline().strip()
|
|
if ':' not in line:
|
|
continue
|
|
|
|
irq_num = line.split(':')[0]
|
|
if not line or int(irq_num) >= 16:
|
|
break
|
|
|
|
if irq_num in irq_list:
|
|
irq_list.remove(irq_num)
|
|
|
|
i_cnt = 0
|
|
print("\t", end="", file=config)
|
|
for irq in irq_list:
|
|
i_cnt += 1
|
|
|
|
if i_cnt == len(irq_list):
|
|
print("{}".format(irq), file=config)
|
|
else:
|
|
print("{}, ".format(irq), end="", file=config)
|
|
|
|
print("\t</AVAILABLE_IRQ_INFO>", file=config)
|
|
print("", file=config)
|
|
|
|
|
|
def dump_system_ram(config):
|
|
"""This will get systemd ram which are usable
|
|
:param config: file pointer that opened for writing board config information
|
|
"""
|
|
print("\t<IOMEM_INFO>", file=config)
|
|
with open(MEM_PATH[0], 'rt') as mem_info:
|
|
|
|
while True:
|
|
line = mem_info.readline().strip('\n')
|
|
if not line:
|
|
break
|
|
|
|
print("\t{}".format(line), file=config)
|
|
|
|
print("\t</IOMEM_INFO>", file=config)
|
|
print("", file=config)
|
|
|
|
|
|
def dump_block_dev(config):
|
|
"""This will get available block device
|
|
:param config: file pointer that opened for writing board config information
|
|
"""
|
|
cmd = 'blkid'
|
|
desc = 'BLOCK_DEVICE_INFO'
|
|
parser_lib.dump_execute(cmd, desc, config)
|
|
print("", file=config)
|
|
|
|
|
|
|
|
def dump_total_mem(config):
|
|
|
|
total_mem = 0
|
|
print("\t<TOTAL_MEM_INFO>", file=config)
|
|
with open(MEM_PATH[1], 'rt') as mem_info:
|
|
while True:
|
|
line = mem_info.readline().strip()
|
|
|
|
if not line:
|
|
break
|
|
|
|
if ':' in line and line.split(':')[0].strip() == "MemTotal":
|
|
total_mem = line.split(':')[1]
|
|
print("\t{}".format(total_mem.strip()), file=config)
|
|
|
|
print("\t</TOTAL_MEM_INFO>", file=config)
|
|
print("", file=config)
|
|
|
|
|
|
def dump_cpu_core_info(config):
|
|
|
|
print("\t<CPU_PROCESSOR_INFO>", file=config)
|
|
with open(CPU_INFO_PATH, 'rt') as cpu_info:
|
|
line = cpu_info.readline()
|
|
|
|
processor_id = int(line.split('-')[0].strip())
|
|
print("\t{}".format(processor_id), end="", file=config)
|
|
|
|
processor_id += 1
|
|
while (processor_id <= int(line.split('-')[1].strip())):
|
|
print(", {}".format(processor_id), end="", file=config)
|
|
processor_id += 1
|
|
|
|
print("", file=config)
|
|
print("\t</CPU_PROCESSOR_INFO>", file=config)
|
|
print("", file=config)
|
|
|
|
|
|
def generate_info(board_info):
|
|
"""Get System Ram information
|
|
:param board_info: this is the file which stores the hardware board information
|
|
"""
|
|
with open(board_info, 'a+') as config:
|
|
|
|
dump_system_ram(config)
|
|
|
|
dump_block_dev(config)
|
|
|
|
dump_ttys(config)
|
|
|
|
dump_free_irqs(config)
|
|
|
|
dump_total_mem(config)
|
|
|
|
dump_cpu_core_info(config)
|