cmake: scripts: support SoC extension
Fixes: #72374 Support extending an existing SoC with new CPU clusters. This commit introduces the following changes to allow an SoC to be extended out-of-tree. The SoC yaml schema is extended to support an extend field which will be used to identify the SoC to be extended with extra CPU clusters. A SoC 'a_soc' can be extended like this: > socs: > extend: a_soc > cpuclusters: > - name: extra_core Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
This commit is contained in:
parent
536d34fa7a
commit
98b186c110
4 changed files with 84 additions and 26 deletions
|
@ -73,19 +73,23 @@ while(TRUE)
|
||||||
string(TOUPPER "${ARCH_V2_NAME}" ARCH_V2_NAME_UPPER)
|
string(TOUPPER "${ARCH_V2_NAME}" ARCH_V2_NAME_UPPER)
|
||||||
set(ARCH_V2_${ARCH_V2_NAME_UPPER}_DIR ${ARCH_V2_DIR})
|
set(ARCH_V2_${ARCH_V2_NAME_UPPER}_DIR ${ARCH_V2_DIR})
|
||||||
elseif(HWM_TYPE MATCHES "^soc|^series|^family")
|
elseif(HWM_TYPE MATCHES "^soc|^series|^family")
|
||||||
cmake_parse_arguments(SOC_V2 "" "NAME;DIR;HWM" "" ${line})
|
cmake_parse_arguments(SOC_V2 "" "NAME;HWM" "DIR" ${line})
|
||||||
|
|
||||||
list(APPEND kconfig_soc_source_dir "${SOC_V2_DIR}")
|
list(APPEND kconfig_soc_source_dir "${SOC_V2_DIR}")
|
||||||
|
string(TOUPPER "${SOC_V2_NAME}" SOC_V2_NAME_UPPER)
|
||||||
|
string(TOUPPER "${HWM_TYPE}" HWM_TYPE_UPPER)
|
||||||
|
|
||||||
if(HWM_TYPE STREQUAL "soc")
|
if(HWM_TYPE STREQUAL "soc")
|
||||||
set(setting_name SOC_${SOC_V2_NAME}_DIR)
|
|
||||||
else()
|
|
||||||
set(setting_name SOC_${HWM_TYPE}_${SOC_V2_NAME}_DIR)
|
|
||||||
endif()
|
|
||||||
# We support both SOC_foo_DIR and SOC_FOO_DIR.
|
# We support both SOC_foo_DIR and SOC_FOO_DIR.
|
||||||
set(${setting_name} ${SOC_V2_DIR})
|
set(SOC_${SOC_V2_NAME}_DIRECTORIES ${SOC_V2_DIR})
|
||||||
string(TOUPPER ${setting_name} setting_name)
|
set(SOC_${SOC_V2_NAME_UPPER}_DIRECTORIES ${SOC_V2_DIR})
|
||||||
set(${setting_name} ${SOC_V2_DIR})
|
list(GET SOC_V2_DIR 0 SOC_${SOC_V2_NAME}_DIR)
|
||||||
|
list(GET SOC_V2_DIR 0 SOC_${SOC_V2_NAME_UPPER}_DIR)
|
||||||
|
else()
|
||||||
|
# We support both SOC_series_foo_DIR and SOC_SERIES_FOO_DIR (and family / FAMILY).
|
||||||
|
set(SOC_${HWM_TYPE}_${SOC_V2_NAME}_DIR ${SOC_V2_DIR})
|
||||||
|
set(SOC_${HWM_TYPE_UPPER}_${SOC_V2_NAME_UPPER}_DIR ${SOC_V2_DIR})
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(idx EQUAL -1)
|
if(idx EQUAL -1)
|
||||||
|
|
|
@ -28,5 +28,10 @@ if(HWMv2)
|
||||||
set(SOC_FAMILY ${CONFIG_SOC_FAMILY})
|
set(SOC_FAMILY ${CONFIG_SOC_FAMILY})
|
||||||
set(SOC_V2_DIR ${SOC_${SOC_NAME}_DIR})
|
set(SOC_V2_DIR ${SOC_${SOC_NAME}_DIR})
|
||||||
set(SOC_FULL_DIR ${SOC_V2_DIR} CACHE PATH "Path to the SoC directory." FORCE)
|
set(SOC_FULL_DIR ${SOC_V2_DIR} CACHE PATH "Path to the SoC directory." FORCE)
|
||||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${SOC_V2_DIR}/soc.yml)
|
set(SOC_DIRECTORIES ${SOC_${SOC_NAME}_DIRECTORIES} CACHE INTERNAL
|
||||||
|
"List of SoC directories for SoC (${SOC_NAME})" FORCE
|
||||||
|
)
|
||||||
|
foreach(dir ${SOC_DIRECTORIES})
|
||||||
|
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/soc.yml)
|
||||||
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -35,6 +35,7 @@ class Systems:
|
||||||
self._socs = []
|
self._socs = []
|
||||||
self._series = []
|
self._series = []
|
||||||
self._families = []
|
self._families = []
|
||||||
|
self._extended_socs = []
|
||||||
|
|
||||||
if soc_yaml is None:
|
if soc_yaml is None:
|
||||||
return
|
return
|
||||||
|
@ -47,12 +48,12 @@ class Systems:
|
||||||
sys.exit(f'ERROR: Malformed yaml {soc_yaml.as_posix()}', e)
|
sys.exit(f'ERROR: Malformed yaml {soc_yaml.as_posix()}', e)
|
||||||
|
|
||||||
for f in data.get('family', []):
|
for f in data.get('family', []):
|
||||||
family = Family(f['name'], folder, [], [])
|
family = Family(f['name'], [folder], [], [])
|
||||||
for s in f.get('series', []):
|
for s in f.get('series', []):
|
||||||
series = Series(s['name'], folder, f['name'], [])
|
series = Series(s['name'], [folder], f['name'], [])
|
||||||
socs = [(Soc(soc['name'],
|
socs = [(Soc(soc['name'],
|
||||||
[c['name'] for c in soc.get('cpuclusters', [])],
|
[c['name'] for c in soc.get('cpuclusters', [])],
|
||||||
folder, s['name'], f['name']))
|
[folder], s['name'], f['name']))
|
||||||
for soc in s.get('socs', [])]
|
for soc in s.get('socs', [])]
|
||||||
series.socs.extend(socs)
|
series.socs.extend(socs)
|
||||||
self._series.append(series)
|
self._series.append(series)
|
||||||
|
@ -61,26 +62,36 @@ class Systems:
|
||||||
family.socs.extend(socs)
|
family.socs.extend(socs)
|
||||||
socs = [(Soc(soc['name'],
|
socs = [(Soc(soc['name'],
|
||||||
[c['name'] for c in soc.get('cpuclusters', [])],
|
[c['name'] for c in soc.get('cpuclusters', [])],
|
||||||
folder, None, f['name']))
|
[folder], None, f['name']))
|
||||||
for soc in f.get('socs', [])]
|
for soc in f.get('socs', [])]
|
||||||
self._socs.extend(socs)
|
self._socs.extend(socs)
|
||||||
self._families.append(family)
|
self._families.append(family)
|
||||||
|
|
||||||
for s in data.get('series', []):
|
for s in data.get('series', []):
|
||||||
series = Series(s['name'], folder, '', [])
|
series = Series(s['name'], [folder], '', [])
|
||||||
socs = [(Soc(soc['name'],
|
socs = [(Soc(soc['name'],
|
||||||
[c['name'] for c in soc.get('cpuclusters', [])],
|
[c['name'] for c in soc.get('cpuclusters', [])],
|
||||||
folder, s['name'], ''))
|
[folder], s['name'], ''))
|
||||||
for soc in s.get('socs', [])]
|
for soc in s.get('socs', [])]
|
||||||
series.socs.extend(socs)
|
series.socs.extend(socs)
|
||||||
self._series.append(series)
|
self._series.append(series)
|
||||||
self._socs.extend(socs)
|
self._socs.extend(socs)
|
||||||
|
|
||||||
socs = [(Soc(soc['name'],
|
for soc in data.get('socs', []):
|
||||||
|
mutual_exclusive = {'name', 'extend'}
|
||||||
|
if len(mutual_exclusive - soc.keys()) < 1:
|
||||||
|
sys.exit(f'ERROR: Malformed content in SoC file: {soc_yaml}\n'
|
||||||
|
f'{mutual_exclusive} are mutual exclusive at this level.')
|
||||||
|
if soc.get('name') is not None:
|
||||||
|
self._socs.append(Soc(soc['name'], [c['name'] for c in soc.get('cpuclusters', [])],
|
||||||
|
[folder], '', ''))
|
||||||
|
elif soc.get('extend') is not None:
|
||||||
|
self._extended_socs.append(Soc(soc['extend'],
|
||||||
[c['name'] for c in soc.get('cpuclusters', [])],
|
[c['name'] for c in soc.get('cpuclusters', [])],
|
||||||
folder, '', ''))
|
[folder], '', ''))
|
||||||
for soc in data.get('socs', [])]
|
else:
|
||||||
self._socs.extend(socs)
|
sys.exit(f'ERROR: Malformed "socs" section in SoC file: {soc_yaml}\n'
|
||||||
|
f'Cannot find one of required keys {mutual_exclusive}.')
|
||||||
|
|
||||||
# Ensure that any runner configuration matches socs and cpuclusters declared in the same
|
# Ensure that any runner configuration matches socs and cpuclusters declared in the same
|
||||||
# soc.yml file
|
# soc.yml file
|
||||||
|
@ -97,7 +108,7 @@ class Systems:
|
||||||
if components and components[-1] == 'ns':
|
if components and components[-1] == 'ns':
|
||||||
components.pop()
|
components.pop()
|
||||||
|
|
||||||
for soc in self._socs:
|
for soc in self._socs + self._extended_socs:
|
||||||
if re.match(fr'^{soc_name}$', soc.name) is not None:
|
if re.match(fr'^{soc_name}$', soc.name) is not None:
|
||||||
if soc.cpuclusters and components:
|
if soc.cpuclusters and components:
|
||||||
check_string = '/'.join(components)
|
check_string = '/'.join(components)
|
||||||
|
@ -133,8 +144,23 @@ class Systems:
|
||||||
def extend(self, systems):
|
def extend(self, systems):
|
||||||
self._families.extend(systems.get_families())
|
self._families.extend(systems.get_families())
|
||||||
self._series.extend(systems.get_series())
|
self._series.extend(systems.get_series())
|
||||||
|
|
||||||
|
for es in self._extended_socs[:]:
|
||||||
|
for s in systems.get_socs():
|
||||||
|
if s.name == es.name:
|
||||||
|
s.extend(es)
|
||||||
|
self._extended_socs.remove(es)
|
||||||
|
break
|
||||||
self._socs.extend(systems.get_socs())
|
self._socs.extend(systems.get_socs())
|
||||||
|
|
||||||
|
for es in systems.get_extended_socs():
|
||||||
|
for s in self._socs:
|
||||||
|
if s.name == es.name:
|
||||||
|
s.extend(es)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self._extended_socs.append(es)
|
||||||
|
|
||||||
def get_families(self):
|
def get_families(self):
|
||||||
return self._families
|
return self._families
|
||||||
|
|
||||||
|
@ -144,6 +170,9 @@ class Systems:
|
||||||
def get_socs(self):
|
def get_socs(self):
|
||||||
return self._socs
|
return self._socs
|
||||||
|
|
||||||
|
def get_extended_socs(self):
|
||||||
|
return self._extended_socs
|
||||||
|
|
||||||
def get_soc(self, name):
|
def get_soc(self, name):
|
||||||
try:
|
try:
|
||||||
return next(s for s in self._socs if s.name == name)
|
return next(s for s in self._socs if s.name == name)
|
||||||
|
@ -156,15 +185,20 @@ class Systems:
|
||||||
class Soc:
|
class Soc:
|
||||||
name: str
|
name: str
|
||||||
cpuclusters: List[str]
|
cpuclusters: List[str]
|
||||||
folder: str
|
folder: List[str]
|
||||||
series: str = ''
|
series: str = ''
|
||||||
family: str = ''
|
family: str = ''
|
||||||
|
|
||||||
|
def extend(self, soc):
|
||||||
|
if self.name == soc.name:
|
||||||
|
self.cpuclusters.extend(soc.cpuclusters)
|
||||||
|
self.folder.extend(soc.folder)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Series:
|
class Series:
|
||||||
name: str
|
name: str
|
||||||
folder: str
|
folder: List[str]
|
||||||
family: str
|
family: str
|
||||||
socs: List[Soc]
|
socs: List[Soc]
|
||||||
|
|
||||||
|
@ -172,7 +206,7 @@ class Series:
|
||||||
@dataclass
|
@dataclass
|
||||||
class Family:
|
class Family:
|
||||||
name: str
|
name: str
|
||||||
folder: str
|
folder: List[str]
|
||||||
series: List[Series]
|
series: List[Series]
|
||||||
socs: List[Soc]
|
socs: List[Soc]
|
||||||
|
|
||||||
|
@ -289,7 +323,7 @@ def dump_v2_system(args, type, system):
|
||||||
info = args.cmakeformat.format(
|
info = args.cmakeformat.format(
|
||||||
TYPE='TYPE;' + type,
|
TYPE='TYPE;' + type,
|
||||||
NAME='NAME;' + system.name,
|
NAME='NAME;' + system.name,
|
||||||
DIR='DIR;' + Path(system.folder).as_posix(),
|
DIR='DIR;' + ';'.join([Path(x).as_posix() for x in system.folder]),
|
||||||
HWM='HWM;' + 'v2'
|
HWM='HWM;' + 'v2'
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -24,7 +24,22 @@ schema;soc-schema:
|
||||||
- type: map
|
- type: map
|
||||||
mapping:
|
mapping:
|
||||||
name:
|
name:
|
||||||
required: true
|
required: true # Note: either name or extend is required, but that is handled in python
|
||||||
|
type: str
|
||||||
|
cpuclusters:
|
||||||
|
include: cpucluster-schema
|
||||||
|
|
||||||
|
schema;soc-extend-schema:
|
||||||
|
required: false
|
||||||
|
type: seq
|
||||||
|
sequence:
|
||||||
|
- type: map
|
||||||
|
mapping:
|
||||||
|
name:
|
||||||
|
required: false # Note: either name or extend is required, but that is handled in python
|
||||||
|
type: str
|
||||||
|
extend:
|
||||||
|
required: false # Note: either name or extend is required, but that is handled in python
|
||||||
type: str
|
type: str
|
||||||
cpuclusters:
|
cpuclusters:
|
||||||
include: cpucluster-schema
|
include: cpucluster-schema
|
||||||
|
@ -60,7 +75,7 @@ mapping:
|
||||||
series:
|
series:
|
||||||
include: series-schema
|
include: series-schema
|
||||||
socs:
|
socs:
|
||||||
include: soc-schema
|
include: soc-extend-schema
|
||||||
vendor:
|
vendor:
|
||||||
required: false
|
required: false
|
||||||
type: str
|
type: str
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue