From fbe44f08d47597b4e95897c51ebbd60e76419bf0 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 17 Dec 2014 13:57:59 +0100 Subject: [PATCH] nova: support to read thread and idle time Issue #813 --- repos/base-nova/include/32bit/nova/syscalls.h | 11 ++++++ repos/base-nova/include/64bit/nova/syscalls.h | 16 +++------ repos/base-nova/src/core/platform.cc | 35 +++++++++++++++++++ 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/repos/base-nova/include/32bit/nova/syscalls.h b/repos/base-nova/include/32bit/nova/syscalls.h index 25f2b297b2..6d30c6eb1f 100644 --- a/repos/base-nova/include/32bit/nova/syscalls.h +++ b/repos/base-nova/include/32bit/nova/syscalls.h @@ -325,5 +325,16 @@ namespace Nova { return syscall_5(NOVA_ASSIGN_GSI, 0, sm, msi_addr, msi_data, si); } + + + ALWAYS_INLINE + inline uint8_t sc_ctrl(unsigned sc, unsigned long long &time) + { + mword_t time_h = 0, time_l = 0; + uint8_t res = syscall_5(NOVA_SC_CTRL, 0, sc, time_h, time_l); + time = time_h; + time = (time << 32ULL) | time_l; + return res; + } } #endif /* _PLATFORM__NOVA_SYSCALLS_H_ */ diff --git a/repos/base-nova/include/64bit/nova/syscalls.h b/repos/base-nova/include/64bit/nova/syscalls.h index 159960e0b6..e65f0a0f72 100644 --- a/repos/base-nova/include/64bit/nova/syscalls.h +++ b/repos/base-nova/include/64bit/nova/syscalls.h @@ -255,18 +255,12 @@ namespace Nova { ALWAYS_INLINE - inline uint8_t sc_ctrl(mword_t sm, Sem_op op, mword_t &time) + inline uint8_t sc_ctrl(mword_t sm, unsigned long long &time) { - mword_t status = rdi(NOVA_SC_CTRL, op, sm); - mword_t time_h; - - uint8_t res = syscall_5(NOVA_SC_CTRL, op, sm, time_h, time); - asm volatile ("syscall" - : "+D" (status), "=S"(time_h), "=d"(time) - : - : "rcx", "r11", "memory"); - - time = (time_h & ~0xFFFFFFFFULL) | (time & 0xFFFFFFFFULL); + mword_t time_h = 0, time_l = 0; + uint8_t res = syscall_5(NOVA_SC_CTRL, 0, sm, time_h, time_l); + time = time_h; + time = (time << 32ULL) | (time_l & 0xFFFFFFFFULL); return res; } diff --git a/repos/base-nova/src/core/platform.cc b/repos/base-nova/src/core/platform.cc index a9c7c7c3b8..306d3d5fdf 100644 --- a/repos/base-nova/src/core/platform.cc +++ b/repos/base-nova/src/core/platform.cc @@ -55,6 +55,12 @@ Utcb *__main_thread_utcb; extern unsigned _prog_img_beg, _prog_img_end; + +extern addr_t sc_idle_base; +addr_t sc_idle_base = 0; + + + /** * Capability selector of root PD */ @@ -263,6 +269,35 @@ Platform::Platform() : nova_die(); } + /* map idle SCs */ + unsigned const log2cpu = log2(hip->cpus()); + if ((1U << log2cpu) != hip->cpus()) { + PERR("number of max CPUs is not of power of 2"); + nova_die(); + } + + sc_idle_base = cap_map()->insert(log2cpu + 1); + if (sc_idle_base & ((1UL << log2cpu) - 1)) { + PERR("unaligned sc_idle_base value %lx", sc_idle_base); + nova_die(); + } + if(map_local(__main_thread_utcb, Obj_crd(0, log2cpu), + Obj_crd(sc_idle_base, log2cpu), true)) + nova_die(); + + /* test reading out idle SCs */ + bool sc_init = true; + for (unsigned i = 0; i < hip->cpus(); i++) { + uint64_t n_time; + uint8_t res = Nova::sc_ctrl(sc_idle_base + i, n_time); + if (res != Nova::NOVA_OK) { + sc_init = false; + printf("%u %u %llu - failed\n", i, res, n_time); + } + } + if (!sc_init) + nova_die(); + /* configure virtual address spaces */ #ifdef __x86_64__ _vm_size = 0x7FFFFFFFF000UL - _vm_base;