sonic-buildimage/platform/mellanox/integration-scripts/hwmgmt_helper.py

201 lines
9.3 KiB
Python
Raw Normal View History

#!/usr/bin/env python
#
# Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
# Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import os
import io
import sys
import argparse
import shutil
import copy
import difflib
import configparser
from helper import *
################################################################################
#### KConfig Processing ####
################################################################################
class KCFGData:
x86_base = OrderedDict()
x86_updated = OrderedDict()
arm_base = OrderedDict()
arm_updated = OrderedDict()
x86_incl = OrderedDict()
arm_incl = OrderedDict()
x86_excl = OrderedDict()
arm_excl = OrderedDict()
x86_down = OrderedDict()
arm_down = OrderedDict()
noarch_incl = OrderedDict()
noarch_excl = OrderedDict()
noarch_down = OrderedDict()
class KConfigTask():
def __init__(self, args):
self.args = args
def read_data(self):
KCFGData.x86_base = FileHandler.read_kconfig(self.args.config_base_amd)
KCFGData.x86_updated = FileHandler.read_kconfig(self.args.config_inc_amd)
if os.path.isfile(self.args.config_inc_down_amd):
print(" -> Downstream Config for x86 found..")
KCFGData.x86_down = FileHandler.read_kconfig(self.args.config_inc_down_amd)
KCFGData.arm_base = FileHandler.read_kconfig(self.args.config_base_arm)
KCFGData.arm_updated = FileHandler.read_kconfig(self.args.config_inc_arm)
if os.path.isfile(self.args.config_inc_down_arm):
print(" -> Downstream Config for arm64 found..")
KCFGData.arm_down = FileHandler.read_kconfig(self.args.config_inc_down_arm)
return
def parse_inc_exc(self, base: OrderedDict, updated: OrderedDict):
# parse the updates/deletions in the Kconfig
add, remove = OrderedDict(), copy.deepcopy(base)
for (key, val) in updated.items():
if val != base.get(key, "empty"):
add[key] = val
# items remaining in remove are the ones to be excluded
if key in remove:
del remove[key]
return add, remove
def parse_noarch_inc_exc(self):
# Filter the common inc/excl out from the arch specific inc/excl
x86_incl_base = copy.deepcopy(KCFGData.x86_incl)
for (key, val) in x86_incl_base.items():
if key in KCFGData.arm_incl and val == KCFGData.arm_incl[key]:
print("-> INFO: NoArch KConfig Inclusion {}:{} found and moving to common marker".format(key, val))
del KCFGData.arm_incl[key]
del KCFGData.x86_incl[key]
KCFGData.noarch_incl[key] = val
x86_excl_base = copy.deepcopy(KCFGData.x86_excl)
for (key, val) in x86_excl_base.items():
if key in KCFGData.arm_excl:
print("-> INFO: NoArch KConfig Exclusion {} found and moving to common marker".format(key))
del KCFGData.arm_excl[key]
del KCFGData.x86_excl[key]
KCFGData.noarch_excl[key] = val
if not (KCFGData.x86_down or KCFGData.arm_down):
return
# Filter the common inc config from the downstream kconfig
x86_down_base = copy.deepcopy(KCFGData.x86_down)
for (key, val) in x86_down_base.items():
if key in KCFGData.arm_down:
print("-> INFO: NoArch KConfig Downstream Inclusion {} found and moving to common marker".format(key))
del KCFGData.arm_down[key]
del KCFGData.x86_down[key]
KCFGData.noarch_down[key] = val
def insert_arm64_section(self, raw_lines: list, arm_data: OrderedDict, is_exclusion=False, section=MLNX_ARM_KFG_SECTION) -> list:
# For arm64, config is not added under markers, but it is added under the section [mellanox-arm64]
# This design decision is taken because of the possibility that there might be conflicting options
# present between two different arm64 platforms
try:
# comment_prefixes needed to also read comments under a section
configParser = configparser.ConfigParser(allow_no_value=True, strict=False, comment_prefixes='////')
configParser.optionxform = str
configParser.read_string("".join(raw_lines))
if not configParser.has_section(MLNX_ARM_KFG_SECTION):
configParser.add_section(MLNX_ARM_KFG_SECTION)
for (key, val) in arm_data.items():
if not is_exclusion:
configParser.set(MLNX_ARM_KFG_SECTION, key, val)
else:
configParser.set(MLNX_ARM_KFG_SECTION, key)
str_io = io.StringIO()
configParser.write(str_io, space_around_delimiters=False)
return str_io.getvalue().splitlines(True)
except Exception as e:
print("-> FATAL: Exception {} found while adding opts under arm".format(str(e)))
raise e
return raw_lines
def get_kconfig_inc(self) -> list:
kcfg_inc_raw = FileHandler.read_raw(os.path.join(self.args.build_root, SLK_KCONFIG))
# Insert common config
noarch_start, noarch_end = FileHandler.find_marker_indices(kcfg_inc_raw, MLNX_NOARCH_MARKER)
kcfg_inc_raw = FileHandler.insert_kcfg_data(kcfg_inc_raw, noarch_start, noarch_end, KCFGData.noarch_incl)
# Insert x86 config
x86_start, x86_end = FileHandler.find_marker_indices(kcfg_inc_raw, MLNX_KFG_MARKER)
kcfg_inc_raw = FileHandler.insert_kcfg_data(kcfg_inc_raw, x86_start, x86_end, KCFGData.x86_incl)
# Insert arm config
kcfg_inc_raw = self.insert_arm64_section(kcfg_inc_raw, KCFGData.arm_incl)
print("\n -> INFO: kconfig-inclusion file is generated \n {}".format("".join(kcfg_inc_raw)))
return kcfg_inc_raw
def get_downstream_kconfig_inc(self, new_kcfg_upstream) -> list:
kcfg_final = copy.deepcopy(new_kcfg_upstream)
# insert common Kconfig
noarch_start, noarch_end = FileHandler.find_marker_indices(kcfg_final, MLNX_NOARCH_MARKER)
noarch_final = OrderedDict(list(KCFGData.noarch_incl.items()) + list(KCFGData.noarch_down.items()))
kcfg_final = FileHandler.insert_kcfg_data(kcfg_final, noarch_start, noarch_end, noarch_final)
# insert x86 Kconfig
x86_start, x86_end = FileHandler.find_marker_indices(kcfg_final, MLNX_KFG_MARKER)
x86_final = OrderedDict(list(KCFGData.x86_incl.items()) + list(KCFGData.x86_down.items()))
kcfg_final = FileHandler.insert_kcfg_data(kcfg_final, x86_start, x86_end, x86_final)
# insert arm Kconfig
arm_final = OrderedDict(list(KCFGData.arm_incl.items()) + list(KCFGData.arm_down.items()))
kcfg_final = self.insert_arm64_section(kcfg_final, arm_final)
# generate diff
diff = difflib.unified_diff(new_kcfg_upstream, kcfg_final, fromfile='a/patch/kconfig-inclusions', tofile="b/patch/kconfig-inclusions", lineterm="\n")
lines = []
for line in diff:
lines.append(line)
print("\n -> INFO: kconfig-inclusion.patch file is generated \n{}".format("".join(lines)))
return lines
def get_kconfig_excl(self) -> list:
# noarch_excl
kcfg_excl_raw = FileHandler.read_raw(os.path.join(self.args.build_root, SLK_KCONFIG_EXCLUDE))
# insert common Kconfig
noarch_start, noarch_end = FileHandler.find_marker_indices(kcfg_excl_raw, MLNX_NOARCH_MARKER)
kcfg_excl_raw = FileHandler.insert_kcfg_excl_data(kcfg_excl_raw, noarch_start, noarch_end, KCFGData.noarch_excl)
# insert x86 Kconfig
x86_start, x86_end = FileHandler.find_marker_indices(kcfg_excl_raw, MLNX_KFG_MARKER)
kcfg_excl_raw = FileHandler.insert_kcfg_excl_data(kcfg_excl_raw, x86_start, x86_end, KCFGData.x86_excl)
# insert arm Kconfig
kcfg_excl_raw = self.insert_arm64_section(kcfg_excl_raw, KCFGData.arm_excl, True)
print("\n -> INFO: kconfig-exclusion file is generated \n{}".format("".join(kcfg_excl_raw)))
return kcfg_excl_raw
def perform(self):
self.read_data()
KCFGData.x86_incl, KCFGData.x86_excl = self.parse_inc_exc(KCFGData.x86_base, KCFGData.x86_updated)
KCFGData.arm_incl, KCFGData.arm_excl = self.parse_inc_exc(KCFGData.arm_base, KCFGData.arm_updated)
self.parse_noarch_inc_exc()
# Get the updated kconfig-inclusions
kcfg_inc_upstream = self.get_kconfig_inc()
FileHandler.write_lines(os.path.join(self.args.build_root, SLK_KCONFIG), kcfg_inc_upstream, True)
# Get the updated kconfig-exclusions
kcfg_excl_upstream = self.get_kconfig_excl()
FileHandler.write_lines(os.path.join(self.args.build_root, SLK_KCONFIG_EXCLUDE), kcfg_excl_upstream, True)
# return the kconfig-inclusions diff
return self.get_downstream_kconfig_inc(kcfg_inc_upstream)