6410e66f35
- Why I did it Add an ability to add arm64 mellanox specific kconfig using the integration tool Fix the existing duplicate kconfig problem by using the vanilla .config Add an ability to patch kconfig-inclusions file. Renamed series.patch to external-changes.patch to reflect the behavior NOTE: Min hw-mgmt version to use with these changes: V.7.0030.2000 not yet upstream but required prio to it. This option will be enabled one the new hw mgmt will be upstream. Depends on sonic-net/sonic-linux-kernel#336 Signed-off-by: Vivek Reddy Karri <vkarri@nvidia.com>
201 lines
9.3 KiB
Python
201 lines
9.3 KiB
Python
#!/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)
|