diff --git a/repos/base-nova/include/nova/syscall-generic.h b/repos/base-nova/include/nova/syscall-generic.h index a9194569c4..1e6a117609 100644 --- a/repos/base-nova/include/nova/syscall-generic.h +++ b/repos/base-nova/include/nova/syscall-generic.h @@ -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 + 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; } } } diff --git a/repos/base-nova/ports/nova.hash b/repos/base-nova/ports/nova.hash index b4fec77779..f74809600d 100644 --- a/repos/base-nova/ports/nova.hash +++ b/repos/base-nova/ports/nova.hash @@ -1 +1 @@ -5e7fa1e56f6ebe1a5c88d7e5278585c543ca3cf3 +39b7b44c4390340ab7b743044ce3fa4301812fd6 diff --git a/repos/base-nova/ports/nova.port b/repos/base-nova/ports/nova.port index 1d8fd79361..8b460f691a 100644 --- a/repos/base-nova/ports/nova.port +++ b/repos/base-nova/ports/nova.port @@ -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)) diff --git a/repos/base-nova/src/core/include/platform.h b/repos/base-nova/src/core/include/platform.h index d992f32b40..615a90aa2e 100644 --- a/repos/base-nova/src/core/include/platform.h +++ b/repos/base-nova/src/core/include/platform.h @@ -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); diff --git a/repos/base-nova/src/core/platform.cc b/repos/base-nova/src/core/platform.cc index 111edf17de..e3e5a6e258 100644 --- a/repos/base-nova/src/core/platform.cc +++ b/repos/base-nova/src/core/platform.cc @@ -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" : ""); }); }