nova: support detection of Intel P & E CPUs

Fixes #4694
This commit is contained in:
Alexander Boettcher 2022-12-01 11:38:03 +01:00 committed by Christian Helmuth
parent 83ac80460e
commit 377f2166a1
5 changed files with 80 additions and 26 deletions

View File

@ -7,7 +7,7 @@
*/
/*
* Copyright (c) 2009 Genode Labs
* Copyright (c) 2009-2022 Genode Labs
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@ -144,6 +144,9 @@ namespace Nova {
uint8_t platform:3;
uint8_t reserved:1;
uint32_t patch;
bool p_core() const { return flags & 0x2; }
bool e_core() const { return flags & 0x4; }
} __attribute__((packed));
unsigned cpu_max() const {
@ -176,38 +179,75 @@ namespace Nova {
/**
* Map kernel cpu ids to virtual cpu ids.
*/
bool remap_cpu_ids(uint8_t *map_cpus, unsigned const boot_cpu) const {
bool remap_cpu_ids(uint16_t *map_cpus, unsigned const boot_cpu) const
{
unsigned const num_cpus = cpus();
unsigned cpu_i = 0;
/* 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))
if (!boot || !is_cpu_enabled(boot_cpu) || boot->e_core())
return false;
map_cpus[cpu_i++] = (uint8_t)boot_cpu;
if (cpu_i >= num_cpus)
return true;
/* assign remaining cores and afterwards all threads to the ids */
for (uint8_t package = 0; package < 255; package++) {
for (uint8_t core = 0; core < 255; core++) {
for (uint8_t thread = 0; thread < 255; thread++) {
/* assign cores + SMT threads first and skip E-cores */
bool done = for_all_cpus([&](auto const &cpu, auto const kernel_cpu_id) {
if (kernel_cpu_id == boot_cpu)
return false;
/* handle normal or P-core */
if (cpu.e_core())
return false;
map_cpus[cpu_i++] = (uint8_t)kernel_cpu_id;
return (cpu_i >= num_cpus);
});
/* assign remaining E-cores */
if (!done) {
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;
map_cpus[cpu_i++] = (uint16_t)kernel_cpu_id;
return (cpu_i >= num_cpus);
});
}
return done;
}
/**
* Iterate over all CPUs in a _ever_ _consistent_ order.
*/
template <typename FUNC>
bool for_all_cpus(FUNC const &func) const
{
for (uint16_t package = 0; package <= 255; package++) {
for (uint16_t core = 0; core <= 255; core++) {
for (uint16_t thread = 0; thread <= 255; thread++) {
for (unsigned i = 0; i < cpu_max(); i++) {
if (i == boot_cpu || !is_cpu_enabled(i))
if (!is_cpu_enabled(i))
continue;
Cpu_desc const * const c = cpu_desc_of_cpu(i);
if (!c)
auto const cpu = cpu_desc_of_cpu(i);
if (!cpu)
continue;
if (!(c->package == package && c->core == core &&
c->thread == thread))
if (!(cpu->package == package && cpu->core == core &&
cpu->thread == thread))
continue;
map_cpus[cpu_i++] = (uint8_t)i;
if (cpu_i >= num_cpus)
return true;
bool done = func(*cpu, i);
if (done)
return done;
}
}
}

View File

@ -1 +1 @@
5e7fa1e56f6ebe1a5c88d7e5278585c543ca3cf3
39b7b44c4390340ab7b743044ce3fa4301812fd6

View File

@ -4,7 +4,7 @@ DOWNLOADS := nova.git
# r10 branch
URL(nova) := https://github.com/alex-ab/NOVA.git
REV(nova) := 0a54bd120ee15672089a0fcacef3b02cc0db523b
REV(nova) := 1e041c00030120392714ba74ef13b1225ccbc1a2
DIR(nova) := src/kernel/nova
PATCHES := $(sort $(wildcard $(REP_DIR)/patches/*.patch))

View File

@ -6,7 +6,7 @@
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
* Copyright (C) 2009-2022 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
@ -49,7 +49,7 @@ namespace Genode {
Affinity::Space _cpus;
/* map of virtual cpu ids in Genode to kernel cpu ids */
uint8_t map_cpu_ids[MAX_SUPPORTED_CPUS];
uint16_t map_cpu_ids[MAX_SUPPORTED_CPUS];
addr_t _map_pages(addr_t phys_page, addr_t pages,
bool guard_page = false);

View File

@ -7,7 +7,7 @@
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
* Copyright (C) 2009-2022 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
@ -309,7 +309,7 @@ Platform::Platform()
{
Hip const &hip = *(Hip *)__initial_sp;
/* check for right API version */
if (hip.api_version != 8)
if (hip.api_version != 9)
nova_die();
/* determine number of available CPUs */
@ -732,9 +732,19 @@ Platform::Platform()
xml.attribute("freq_khz" , hip.tsc_freq);
});
xml.node("cpus", [&] () {
hip.for_each_enabled_cpu([&](Hip::Cpu_desc const &cpu, unsigned i) {
for_each_location([&](Affinity::Location &location) {
unsigned const kernel_cpu_id = Platform::kernel_cpu_id(location);
auto const cpu_ptr = hip.cpu_desc_of_cpu(kernel_cpu_id);
if (!cpu_ptr)
return;
auto const &cpu = *cpu_ptr;
xml.node("cpu", [&] () {
xml.attribute("id", i);
xml.attribute("xpos", location.xpos());
xml.attribute("ypos", location.ypos());
xml.attribute("id", kernel_cpu_id);
xml.attribute("package", cpu.package);
xml.attribute("core", cpu.core);
xml.attribute("thread", cpu.thread);
@ -743,6 +753,8 @@ Platform::Platform()
xml.attribute("stepping", String<5>(Hex(cpu.stepping)));
xml.attribute("platform", String<5>(Hex(cpu.platform)));
xml.attribute("patch", String<12>(Hex(cpu.patch)));
if (cpu.p_core()) xml.attribute("cpu_type", "P");
if (cpu.e_core()) xml.attribute("cpu_type", "E");
});
});
});
@ -780,11 +792,13 @@ Platform::Platform()
Genode::String<16> text ("failure");
if (cpu)
text = Genode::String<16>(cpu->package, ":",
cpu->core, ":", cpu->thread);
cpu->core, ":", cpu->thread,
cpu->e_core() ? " E" :
cpu->p_core() ? " P" : "");
log(" remap (", location.xpos(), "x", location.ypos(),") -> ",
kernel_cpu_id, " - ", text, ") ",
boot_cpu() == kernel_cpu_id ? "boot cpu" : "");
kernel_cpu_id, " - ", text,
boot_cpu() == kernel_cpu_id ? " boot cpu" : "");
});
}