Files
acrn-hypervisor/misc/acrn-config/board_config/pci_devices_h.py
Wei Liu d44440f734 acrn-config: print warning if MMIO BAR size above 4G
Currently MMIO BAR size not support size above 4G,
print warning to user to set the MMIO size in 4G region from BIOS.

Target-On: #3854
Signed-off-by: Wei Liu <weix.w.liu@intel.com>
Acked-by: Victor Sun <victor.sun@intel.com>
2019-11-29 09:05:33 +08:00

174 lines
5.3 KiB
Python

# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
import collections
import board_cfg_lib
PCI_HEADER = r"""
#ifndef PCI_DEVICES_H_
#define PCI_DEVICES_H_
"""
PCI_END_HEADER = r"""
#endif /* PCI_DEVICES_H_ */"""
def get_value_after_str(line, key):
""" Get the value after cstate string """
idx = 0
line_in_list = line.split()
for idx_key, val in enumerate(line_in_list):
if val == key:
idx = idx_key
break
return line_in_list[idx + 1]
def parser_pci():
""" Parse PCI lines """
cur_bdf = 0
prev_bdf = 0
tmp_bar_dic = {}
pci_dev_dic = {}
pci_bar_dic = {}
above_4G_mmio = False
bar_addr = bar_num = '0'
pci_lines = board_cfg_lib.get_info(
board_cfg_lib.BOARD_INFO_FILE, "<PCI_DEVICE>", "</PCI_DEVICE>")
for line in pci_lines:
# get pci bar information into pci_bar_dic
if "Region" in line and "Memory at" in line:
bar_num = line.split()[1].strip(':')
bar_addr = get_value_after_str(line, "at")
if int(bar_addr, 16) > 0xffffffff:
above_4G_mmio = True
tmp_bar_dic[int(bar_num)] = hex(int(bar_addr, 16))
else:
prev_bdf = cur_bdf
pci_bdf = line.split()[0]
pci_sub_name = " ".join(line.split(':')[1].split()[1:])
# remove '[*]' in pci subname
if '[' in pci_sub_name:
pci_sub_name = pci_sub_name.rsplit('[', 1)[0]
pci_dev_dic[pci_bdf] = pci_sub_name
cur_bdf = pci_bdf
if not prev_bdf:
prev_bdf = cur_bdf
if tmp_bar_dic and cur_bdf != prev_bdf:
pci_bar_dic[prev_bdf] = tmp_bar_dic
# clear the tmp_bar_dic before store the next dic
tmp_bar_dic = {}
if above_4G_mmio:
board_cfg_lib.print_yel("Currently ACRN does not support BAR size above 4G, please double check below possible items in BIOS:\n\
1. GPU Aperture size is less than 1GB;\n\
2. the device MMIO mapping region is below 4GB", warn=True)
# output all the pci device list to pci_device.h
sub_name_count = collections.Counter(pci_dev_dic.values())
if tmp_bar_dic:
pci_bar_dic[cur_bdf] = tmp_bar_dic
return (pci_dev_dic, pci_bar_dic, sub_name_count)
def write_pbdf(i_cnt, bdf, subname, config):
"""
Parser and generate pbdf
:param i_cnt: the number of pci devices have the same PCI subname
:param bdf: it is a string what contains BDF
:param subname: it is a string belong to PIC subname
:param config: it is a file pointer of pci information for writing to
"""
# if there is only one host bridge, then will discard the index of suffix
if i_cnt == 0 and subname.upper() == "HOST BRIDGE":
tmp_sub_name = "_".join(subname.split()).upper()
else:
if '-' in subname:
tmp_sub_name = board_cfg_lib.undline_name(subname) + "_" + str(i_cnt)
else:
tmp_sub_name = "_".join(subname.split()).upper() + "_" + str(i_cnt)
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), end="", file=config)
def write_vbar(bdf, pci_bar_dic, config):
"""
Parser and generate vbar
:param bdf: it is a string what contains BDF
:param pci_bar_dic: it is a dictionary of pci vbar for those BDF
:param config: it is a file pointer of pci information for writing to
"""
tail = 0
align = ' ' * 48
if bdf in pci_bar_dic.keys():
bar_list = list(pci_bar_dic[bdf].keys())
bar_len = len(bar_list)
bar_num = 0
for bar_i in bar_list:
if tail == 0:
print(", \\", file=config)
tail += 1
bar_num += 1
bar_val = pci_bar_dic[bdf][bar_i]
if bar_num == bar_len:
print("{}.vbar_base[{}] = {}UL".format(align, bar_i, bar_val), file=config)
else:
print("{}.vbar_base[{}] = {}UL, \\".format(
align, bar_i, bar_val), file=config)
# print("", file=config)
else:
print("", 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)
(pci_dev_dic, pci_bar_dic, sub_name_count) = parser_pci()
compared_bdf = []
for cnt_sub_name in sub_name_count.keys():
i_cnt = 0
for bdf, subname in pci_dev_dic.items():
if cnt_sub_name == subname and bdf not in compared_bdf:
compared_bdf.append(bdf)
else:
continue
write_pbdf(i_cnt, bdf, subname, config)
write_vbar(bdf, pci_bar_dic, config)
i_cnt += 1
# write the end to the pci devices
print("{0}".format(PCI_END_HEADER), file=config)