From 1a82b664efbd3f447bf752f1e6b5abd33903c8aa Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Fri, 5 Oct 2012 11:35:14 +0200 Subject: [PATCH] nova: determine number of CPUs Issue #813 --- base-nova/include/nova/syscall-generic.h | 16 ++++++++++++++++ base-nova/src/core/include/platform.h | 4 ++++ base-nova/src/core/platform.cc | 6 +++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/base-nova/include/nova/syscall-generic.h b/base-nova/include/nova/syscall-generic.h index 07dc41333c..f5676eecbf 100644 --- a/base-nova/include/nova/syscall-generic.h +++ b/base-nova/include/nova/syscall-generic.h @@ -123,6 +123,22 @@ namespace Nova { bool has_feature_vmx() const { return feature_flags & (1 << 1); } bool has_feature_svm() const { return feature_flags & (1 << 2); } + + unsigned cpu_max() const { + return (mem_desc_offset - cpu_desc_offset) / cpu_desc_size; } + + unsigned cpus() const { + unsigned cpu_num = 0; + const char * cpu_desc = + reinterpret_cast(this) + cpu_desc_offset; + + for (unsigned i = 0; i < cpu_max(); i++) { + if ((*cpu_desc) & 0x1) cpu_num++; + cpu_desc += cpu_desc_size; + } + + return cpu_num; + } } __attribute__((packed)); diff --git a/base-nova/src/core/include/platform.h b/base-nova/src/core/include/platform.h index 77202cc18d..17c308b05d 100644 --- a/base-nova/src/core/include/platform.h +++ b/base-nova/src/core/include/platform.h @@ -42,6 +42,9 @@ namespace Genode { const addr_t _vm_base; size_t _vm_size; + /* available CPUs */ + unsigned _cpus; + addr_t _map_page(addr_t const phys_page, addr_t const pages, bool const extra_page); void _unmap_page(addr_t const phys, addr_t const virt, @@ -71,6 +74,7 @@ namespace Genode { void wait_for_exit(); bool supports_unmap() { return true; } + unsigned num_cpus() const { return _cpus; } /******************* diff --git a/base-nova/src/core/platform.cc b/base-nova/src/core/platform.cc index fa9257dbec..6fdd202f98 100644 --- a/base-nova/src/core/platform.cc +++ b/base-nova/src/core/platform.cc @@ -289,13 +289,16 @@ static void init_core_page_fault_handler() Platform::Platform() : _io_mem_alloc(core_mem_alloc()), _io_port_alloc(core_mem_alloc()), _irq_alloc(core_mem_alloc()), - _vm_base(0x1000), _vm_size(0) + _vm_base(0x1000), _vm_size(0), _cpus(1) { Hip *hip = (Hip *)__initial_sp; /* check for right API version */ if (hip->api_version != 6) nova_die(); + /* determine number of available CPUs */ + _cpus = hip->cpus(); + /* register UTCB of main thread */ __main_thread_utcb = (Utcb *)(__initial_sp - get_page_size()); @@ -338,6 +341,7 @@ Platform::Platform() : if (verbose_boot_info) { printf("Hypervisor %s VMX\n", hip->has_feature_vmx() ? "features" : "does not feature"); printf("Hypervisor %s SVM\n", hip->has_feature_svm() ? "features" : "does not feature"); + printf("Hypervisor reports %u CPU%c\n", _cpus, _cpus > 1 ? 's' : ' '); } /* initialize core allocators */