nova: support to read thread and idle time

Issue #813
This commit is contained in:
Alexander Boettcher 2014-12-17 13:57:59 +01:00 committed by Christian Helmuth
parent 4f88fe7bd0
commit fbe44f08d4
3 changed files with 51 additions and 11 deletions

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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;