nova: create core threads on boot cpu

The boot CPU is not necessarily 0 as currently assumed for base-nova.
Replace all hard coded values by the actual boot cpu number.

Issue #814
This commit is contained in:
Alexander Boettcher 2013-07-10 14:35:54 +02:00 committed by Norman Feske
parent 0079179f05
commit 0e83b0b093
7 changed files with 37 additions and 17 deletions

View File

@ -253,9 +253,8 @@ Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size,
_tid.ec_sel = ec_cap.local_name(); _tid.ec_sel = ec_cap.local_name();
} }
else { else {
enum { CPU_NO = 0 }; //XXX find out the boot cpu /* tell thread starting code to use boot CPU */
/* tell thread starting code on which CPU to let run the server thread */ *reinterpret_cast<addr_t *>(stack_top()) = ~0UL;
*reinterpret_cast<addr_t *>(stack_top()) = CPU_NO;
/* /*
* Required for core threads (creates local EC) * Required for core threads (creates local EC)

View File

@ -20,10 +20,10 @@
/* local includes */ /* local includes */
#include <echo.h> #include <echo.h>
#include <nova_util.h>
enum { enum {
ECHO_STACK_SIZE = 1024, ECHO_STACK_SIZE = 1024,
ECHO_CPU_NO = 0,
ECHO_GLOBAL = false, ECHO_GLOBAL = false,
ECHO_EXC_BASE = 0 ECHO_EXC_BASE = 0
}; };
@ -72,8 +72,9 @@ Echo::Echo(Genode::addr_t utcb_addr)
/* create echo EC */ /* create echo EC */
Genode::addr_t pd_sel = Genode::Platform_pd::pd_core_sel(); Genode::addr_t pd_sel = Genode::Platform_pd::pd_core_sel();
uint8_t res = create_ec(_ec_sel, pd_sel, ECHO_CPU_NO, utcb_addr, uint8_t res = create_ec(_ec_sel, pd_sel, boot_cpu(), utcb_addr,
(mword_t)echo_stack_top(), ECHO_EXC_BASE, ECHO_GLOBAL); reinterpret_cast<mword_t>(echo_stack_top()),
ECHO_EXC_BASE, ECHO_GLOBAL);
/* make error condition visible by raising an unhandled page fault */ /* make error condition visible by raising an unhandled page fault */
if (res) { ((void (*)())(res*0x10000UL))(); } if (res) { ((void (*)())(res*0x10000UL))(); }

View File

@ -28,6 +28,24 @@
enum { verbose_local_map = false }; enum { verbose_local_map = false };
/**
* Return boot CPU number. It is required if threads in core should be placed
* on the same CPU as the main thread.
*/
inline Genode::addr_t boot_cpu()
{
/**
* Initial value of ax and di register, saved by the crt0 startup code
* and SOLELY VALID in 'core' !!!
*
* For x86_32 - __initial_ax contains the number of the boot CPU.
* For x86_64 - __initial_di contains the number of the boot CPU.
*/
extern Genode::addr_t __initial_ax;
extern Genode::addr_t __initial_di;
return (sizeof(void *) > 4) ? __initial_di : __initial_ax;
}
/** /**
* Establish a mapping * Establish a mapping

View File

@ -67,8 +67,8 @@ class Irq_thread : public Thread_base
*sp = reinterpret_cast<addr_t>(_thread_start); *sp = reinterpret_cast<addr_t>(_thread_start);
/* create global EC */ /* create global EC */
enum { CPU_NO = 0, GLOBAL = true }; enum { GLOBAL = true };
uint8_t res = create_ec(_tid.ec_sel, pd_sel, CPU_NO, uint8_t res = create_ec(_tid.ec_sel, pd_sel, boot_cpu(),
utcb, (mword_t)sp, _tid.exc_pt_sel, GLOBAL); utcb, (mword_t)sp, _tid.exc_pt_sel, GLOBAL);
if (res != NOVA_OK) { if (res != NOVA_OK) {
PERR("%p - create_ec returned %d", this, res); PERR("%p - create_ec returned %d", this, res);
@ -139,11 +139,10 @@ class Genode::Irq_proxy_component : public Irq_proxy<Irq_thread>
} }
/* assign IRQ to CPU */ /* assign IRQ to CPU */
enum { CPU = 0 };
addr_t msi_addr = 0; addr_t msi_addr = 0;
addr_t msi_data = 0; addr_t msi_data = 0;
uint8_t res = Nova::assign_gsi(_irq_sel, _dev_mem, CPU, msi_addr, msi_data); uint8_t res = Nova::assign_gsi(_irq_sel, _dev_mem, boot_cpu(),
msi_addr, msi_data);
if (res != Nova::NOVA_OK) if (res != Nova::NOVA_OK)
PERR("Error: assign_pci failed -irq:dev:msi_addr:msi_data " PERR("Error: assign_pci failed -irq:dev:msi_addr:msi_data "
"%lx:%lx:%lx:%lx", _irq_number, _dev_mem, msi_addr, "%lx:%lx:%lx:%lx", _irq_number, _dev_mem, msi_addr,

View File

@ -38,8 +38,7 @@ Native_utcb *main_thread_utcb();
/** /**
* Initial value of esp register, saved by the crt0 startup code * Initial value of esp register, saved by the crt0 startup code.
*
* This value contains the address of the hypervisor information page. * This value contains the address of the hypervisor information page.
*/ */
extern addr_t __initial_sp; extern addr_t __initial_sp;
@ -255,14 +254,13 @@ static void init_core_page_fault_handler()
{ {
/* create echo EC */ /* create echo EC */
enum { enum {
CPU_NO = 0,
GLOBAL = false, GLOBAL = false,
EXC_BASE = 0 EXC_BASE = 0
}; };
addr_t ec_sel = cap_selector_allocator()->alloc(); addr_t ec_sel = cap_selector_allocator()->alloc();
uint8_t ret = create_ec(ec_sel, __core_pd_sel, CPU_NO, uint8_t ret = create_ec(ec_sel, __core_pd_sel, boot_cpu(),
CORE_PAGER_UTCB_ADDR, core_pager_stack_top(), CORE_PAGER_UTCB_ADDR, core_pager_stack_top(),
EXC_BASE, GLOBAL); EXC_BASE, GLOBAL);
if (ret) if (ret)
@ -341,7 +339,8 @@ Platform::Platform() :
if (verbose_boot_info) { if (verbose_boot_info) {
printf("Hypervisor %s VMX\n", hip->has_feature_vmx() ? "features" : "does not feature"); 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 %s SVM\n", hip->has_feature_svm() ? "features" : "does not feature");
printf("Hypervisor reports %u CPU%c\n", _cpus, _cpus > 1 ? 's' : ' '); printf("Hypervisor reports %u CPU%c - boot CPU is %lu\n",
_cpus, _cpus > 1 ? 's' : ' ', boot_cpu());
} }
/* initialize core allocators */ /* initialize core allocators */

View File

@ -326,7 +326,7 @@ Weak_ptr<Address_space> Platform_thread::address_space()
Platform_thread::Platform_thread(const char *name, unsigned, int thread_id) Platform_thread::Platform_thread(const char *name, unsigned, int thread_id)
: :
_pd(0), _pager(0), _id_base(cap_selector_allocator()->alloc(1)), _pd(0), _pager(0), _id_base(cap_selector_allocator()->alloc(1)),
_sel_exc_base(Native_thread::INVALID_INDEX), _cpu_no(0), //XXX find out boot CPU _sel_exc_base(Native_thread::INVALID_INDEX), _cpu_no(boot_cpu()),
_is_main_thread(false), _is_vcpu(false) _is_main_thread(false), _is_vcpu(false)
{ {
strncpy(_name, name, sizeof(_name)); strncpy(_name, name, sizeof(_name));

View File

@ -84,6 +84,10 @@ void Thread_base::start()
addr_t pd_sel = Platform_pd::pd_core_sel(); addr_t pd_sel = Platform_pd::pd_core_sel();
addr_t cpu_no = *reinterpret_cast<addr_t *>(stack_top()); addr_t cpu_no = *reinterpret_cast<addr_t *>(stack_top());
/* server code sets this value */
if (cpu_no == ~0UL)
cpu_no = boot_cpu();
/* create local EC */ /* create local EC */
enum { LOCAL_THREAD = false }; enum { LOCAL_THREAD = false };
uint8_t res = create_ec(_tid.ec_sel, pd_sel, cpu_no, uint8_t res = create_ec(_tid.ec_sel, pd_sel, cpu_no,