mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 11:27:29 +00:00
nova: support to run on e-core only SOCs
The code to group together SMT threads of one CPU and to move P-Core to the beginning of Genode's affinity-space, did not consider to run on SOCs with only E-Core CPUs. Re-structure the code to support e-Core only SOCs. Additionally, provide a fallback mapping in case of CPU id reordering problems. Track faulty re-mapping and delay the reporting until core_log is initialized, so that the warnings is visible to consumers, e.g. on Sculpt OS. Related to discussion of #5304 Fixes #5307
This commit is contained in:
parent
044d8bca44
commit
eaadc6aad6
@ -178,21 +178,39 @@ namespace Nova {
|
||||
}
|
||||
|
||||
/**
|
||||
* Map kernel cpu ids to virtual cpu ids.
|
||||
* Resort CPU ids such, that
|
||||
* - the boot CPU id is ever logical CPU id 0
|
||||
* - SMT threads of one CPU have logical CPU ids close together
|
||||
* - P-Core has a smaller logical CPU id than E-Core CPUs
|
||||
*
|
||||
* Returns true, if re-mapping succeeded otherwise false.
|
||||
*
|
||||
* In case of failure, map_cpus will contain a 1:1 fallback mapping
|
||||
* without any sorting as mentioned above.
|
||||
*/
|
||||
bool remap_cpu_ids(uint16_t *map_cpus, unsigned const boot_cpu) const
|
||||
bool remap_cpu_ids(uint16_t *map_cpus, unsigned const max_cpus,
|
||||
unsigned const boot_cpu) const
|
||||
{
|
||||
unsigned const num_cpus = cpus();
|
||||
bool too_many_cpus = false;
|
||||
unsigned cpu_i = 0;
|
||||
|
||||
/* fallback lambda in case re-ordering fails */
|
||||
auto remap_failure = [&] {
|
||||
for (uint16_t i = 0; i < max_cpus; i++) { map_cpus[i] = i; }
|
||||
return false;
|
||||
};
|
||||
|
||||
/* assign boot cpu ever the virtual cpu id 0 */
|
||||
Cpu_desc const * const boot = cpu_desc_of_cpu(boot_cpu);
|
||||
if (!boot || !is_cpu_enabled(boot_cpu) || boot->e_core())
|
||||
return false;
|
||||
if (!boot)
|
||||
return remap_failure();
|
||||
|
||||
map_cpus[cpu_i++] = (uint8_t)boot_cpu;
|
||||
if (cpu_i >= num_cpus)
|
||||
return true;
|
||||
if (cpu_i >= max_cpus)
|
||||
return remap_failure();
|
||||
|
||||
/* assign cores + SMT threads first and skip E-cores */
|
||||
bool done = for_all_cpus([&](auto const &cpu, auto const kernel_cpu_id) {
|
||||
@ -204,25 +222,32 @@ namespace Nova {
|
||||
return false;
|
||||
|
||||
map_cpus[cpu_i++] = (uint8_t)kernel_cpu_id;
|
||||
return (cpu_i >= num_cpus);
|
||||
|
||||
too_many_cpus = !!(cpu_i >= max_cpus);
|
||||
|
||||
return (cpu_i >= num_cpus || too_many_cpus);
|
||||
});
|
||||
|
||||
if (done)
|
||||
return too_many_cpus ? remap_failure() : true;
|
||||
|
||||
/* assign remaining E-cores */
|
||||
if (!done) {
|
||||
done = for_all_cpus([&](auto &cpu, auto &kernel_cpu_id) {
|
||||
if (kernel_cpu_id == boot_cpu)
|
||||
return false;
|
||||
done = for_all_cpus([&](auto &cpu, auto &kernel_cpu_id) {
|
||||
if (kernel_cpu_id == boot_cpu)
|
||||
return false;
|
||||
|
||||
/* handle solely E-core */
|
||||
if (!cpu.e_core())
|
||||
return false;
|
||||
/* handle solely E-core */
|
||||
if (!cpu.e_core())
|
||||
return false;
|
||||
|
||||
map_cpus[cpu_i++] = (uint16_t)kernel_cpu_id;
|
||||
return (cpu_i >= num_cpus);
|
||||
});
|
||||
}
|
||||
map_cpus[cpu_i++] = (uint16_t)kernel_cpu_id;
|
||||
|
||||
return done;
|
||||
too_many_cpus = !!(cpu_i >= max_cpus);
|
||||
|
||||
return (cpu_i >= num_cpus || too_many_cpus);
|
||||
});
|
||||
|
||||
return too_many_cpus ? remap_failure() : done;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -307,6 +307,8 @@ Core::Platform::Platform()
|
||||
_irq_alloc(&core_mem_alloc()),
|
||||
_vm_base(0x1000), _vm_size(0), _cpus(Affinity::Space(1,1))
|
||||
{
|
||||
bool warn_reorder = false;
|
||||
|
||||
Hip const &hip = *(Hip *)__initial_sp;
|
||||
/* check for right API version */
|
||||
if (hip.api_version != 9)
|
||||
@ -365,15 +367,9 @@ Core::Platform::Platform()
|
||||
}
|
||||
|
||||
/* init genode cpu ids based on kernel cpu ids (used for syscalls) */
|
||||
if (sizeof(map_cpu_ids) / sizeof(map_cpu_ids[0]) < hip.cpu_max()) {
|
||||
error("number of max CPUs is larger than expected - ", hip.cpu_max(),
|
||||
" vs ", sizeof(map_cpu_ids) / sizeof(map_cpu_ids[0]));
|
||||
nova_die();
|
||||
}
|
||||
if (!hip.remap_cpu_ids(map_cpu_ids, (unsigned)boot_cpu())) {
|
||||
error("re-ording cpu_id failed");
|
||||
nova_die();
|
||||
}
|
||||
warn_reorder = !hip.remap_cpu_ids(map_cpu_ids,
|
||||
sizeof(map_cpu_ids) / sizeof(map_cpu_ids[0]),
|
||||
(unsigned)boot_cpu());
|
||||
|
||||
/* map idle SCs */
|
||||
unsigned const log2cpu = log2(hip.cpu_max());
|
||||
@ -773,6 +769,10 @@ Core::Platform::Platform()
|
||||
new (core_mem_alloc())
|
||||
Rom_module(_rom_fs, "kernel_log", hyp_log, hyp_log_size);
|
||||
|
||||
/* show all warnings/errors after init_core_log setup core_log */
|
||||
if (warn_reorder)
|
||||
warning("re-ordering of CPU ids for SMT and P/E cores failed");
|
||||
|
||||
if (verbose_boot_info) {
|
||||
if (hip.has_feature_iommu())
|
||||
log("Hypervisor features IOMMU");
|
||||
|
Loading…
x
Reference in New Issue
Block a user