1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

use HALT state to shutdown the system, otherwise PAUSE, check EST & P-states

This commit is contained in:
Stefan Lankes 2016-03-04 23:57:15 +01:00
parent 2c200558f1
commit 6514e2d8fd
7 changed files with 137 additions and 10 deletions

View file

@ -64,6 +64,7 @@ extern "C" {
// feature list 0x00000001 (ecx)
#define CPU_FEATURE_MWAIT (1 << 3)
#define CPU_FEATURE_VMX (1 << 5)
#define CPU_FEATURE_EST (1 << 7)
#define CPU_FEATURE_SSE3 (1 << 9)
#define CPU_FEATURE_FMA (1 << 12)
#define CPU_FEATURE_DCA (1 << 18)
@ -87,6 +88,9 @@ extern "C" {
#define CPU_FEATURE_FSGSBASE (1 << 0)
#define CPU_FEATURE_AVX2 (1 << 5)
// feature list 0x00000006
#define CPU_FEATURE_IDA (1 << 0)
#define CPU_FEATURE_HWP (1 << 10)
/*
* EFLAGS bits
@ -197,13 +201,31 @@ extern "C" {
#define MSR_XAPIC_ENABLE (1UL << 11)
#define MSR_X2APIC_ENABLE (1UL << 10)
#define MSR_PLATFORM_INFO 0x000000ce
#define MSR_IA32_MPERF 0x000000e7
#define MSR_IA32_APERF 0x000000e8
#define MSR_IA32_MISC_ENABLE 0x000001a0
#define MSR_IA32_FEATURE_CONTROL 0x0000003a
#define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0
#define MSR_IA32_PERF_STATUS 0x00000198
#define MSR_IA32_PERF_CTL 0x00000199
#define MSR_IA32_CR_PAT 0x00000277
#define MSR_MTRRdefType 0x000002ff
#define MSR_PPERF 0x0000064e
#define MSR_PERF_LIMIT_REASONS 0x0000064f
#define MSR_PM_ENABLE 0x00000770
#define MSR_HWP_CAPABILITIES 0x00000771
#define MSR_HWP_REQUEST_PKG 0x00000772
#define MSR_HWP_INTERRUPT 0x00000773
#define MSR_HWP_REQUEST 0x00000774
#define MSR_HWP_STATUS 0x00000777
#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << 16)
#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << 20)
#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38)
#define MSR_MTRRfix64K_00000 0x00000250
#define MSR_MTRRfix16K_80000 0x00000258
#define MSR_MTRRfix16K_A0000 0x00000259
@ -290,6 +312,11 @@ inline static uint32_t has_vmx(void) {
return (cpu_info.feature2 & CPU_FEATURE_VMX);
}
inline static uint32_t has_est(void)
{
return (cpu_info.feature2 & CPU_FEATURE_EST);
}
inline static uint32_t has_sse3(void) {
return (cpu_info.feature2 & CPU_FEATURE_SSE3);
}
@ -679,6 +706,10 @@ static inline size_t lsb(size_t i)
return ret;
}
/** @brief: print current pstate
*/
void dump_pstate(void);
/// A one-instruction-do-nothing
#define NOP asm volatile ("nop")
/// The PAUSE instruction provides a hint to the processor that the code sequence is a spin-wait loop.

View file

@ -421,7 +421,7 @@ int apic_calibration(void)
/* wait for the next time slice */
while ((ticks = get_clock_tick()) - old == 0)
HALT;
PAUSE;
flags = irq_nested_disable();
lapic_write(APIC_DCR, 0xB); // set it to 1 clock increments
@ -431,7 +431,7 @@ int apic_calibration(void)
/* wait 3 time slices to determine a ICR */
while (get_clock_tick() - ticks < 3)
HALT;
PAUSE;
icr = (0xFFFFFFFFUL - lapic_read(APIC_CCR)) / 3;
@ -802,6 +802,8 @@ void shutdown_system(void)
if (if_bootprocessor) {
kprintf("Try to shutdown HermitCore\n");
dump_pstate();
while(atomic_int32_read(&cpu_online) != 1)
PAUSE;

View file

@ -190,13 +190,13 @@ uint32_t detect_cpu_frequency(void)
/* wait for the next time slice */
while((ticks = get_clock_tick()) - old == 0)
HALT;
PAUSE;
rmb();
start = rdtsc();
/* wait a second to determine the frequency */
while(get_clock_tick() - ticks < TIMER_FREQ)
HALT;
PAUSE;
rmb();
end = rdtsc();
@ -206,6 +206,93 @@ uint32_t detect_cpu_frequency(void)
return cpu_freq;
}
static int get_min_pstate(void)
{
uint64_t value;
value = rdmsr(MSR_PLATFORM_INFO);
return (value >> 40) & 0xFF;
}
static int get_max_pstate(void)
{
uint64_t value;
value = rdmsr(MSR_PLATFORM_INFO);
return (value >> 8) & 0xFF;
}
static uint8_t is_turbo = 0;
static int max_pstate, min_pstate;
static void set_max_pstate(void)
{
uint64_t v = max_pstate << 8;
if (is_turbo)
v |= (1ULL << 32);
wrmsr(MSR_IA32_PERF_CTL, v);
}
void dump_pstate(void)
{
kprintf("P-State 0x%x - 0x%x\n", min_pstate, max_pstate);
kprintf("PERF CTL 0x%llx\n", rdmsr(MSR_IA32_PERF_CTL));
kprintf("PERF STATUS 0x%llx\n", rdmsr(MSR_IA32_PERF_STATUS));
}
static void check_est(uint8_t out)
{
uint32_t a=0, b=0, c=0, d=0;
uint64_t v;
if (!has_est())
return;
if (out)
kputs("System supports Enhanced SpeedStep Technology\n");
// enable Enhanced SpeedStep Technology
v = rdmsr(MSR_IA32_MISC_ENABLE);
if (!(v & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
if (out)
kputs("Linux doesn't enable Enhanced SpeedStep Technology\n");
return;
}
if (v & MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK) {
if (out)
kputs("Enhanced SpeedStep Technology is locked\n");
return;
}
if (v & MSR_IA32_MISC_ENABLE_TURBO_DISABLE) {
if (out)
kputs("Turbo Mode is disabled\n");
} else is_turbo=1;
cpuid(6, &a, &b, &c, &d);
if (c & CPU_FEATURE_IDA) {
if (out)
kprintf("Found P-State hardware coordination feedback capability bit\n");
}
if (c & CPU_FEATURE_HWP) {
if (out)
kprintf("P-State HWP enabled\n");
}
max_pstate = get_max_pstate();
min_pstate = get_min_pstate();
set_max_pstate();
if (out)
dump_pstate();
return;
}
int cpu_detection(void) {
uint64_t xcr0;
uint32_t a=0, b=0, c=0, d=0, level = 0;
@ -403,6 +490,9 @@ int cpu_detection(void) {
fpu_init = fpu_init_fxsr;
}
// initialize Enhanced SpeedStep Technology
check_est(first_time);
if (first_time && on_hypervisor()) {
uint32_t c, d;
char vendor_id[13];
@ -426,7 +516,7 @@ int cpu_detection(void) {
uint64_t msr;
kprintf("IA32_MISC_ENABLE 0x%llx\n", rdmsr(MSR_IA32_MISC_ENABLE));
kprintf("IA32_FEATURE_CONTROL 0x%llx\n", rdmsr(MSR_IA32_FEATURE_CONTROL));
//kprintf("IA32_FEATURE_CONTROL 0x%llx\n", rdmsr(MSR_IA32_FEATURE_CONTROL));
//kprintf("IA32_ENERGY_PERF_BIAS 0x%llx\n", rdmsr(MSR_IA32_ENERGY_PERF_BIAS));
//kprintf("IA32_PERF_STATUS 0x%llx\n", rdmsr(MSR_IA32_PERF_STATUS));
if (has_pat()) {

View file

@ -117,7 +117,7 @@ size_t* get_current_stack(void)
if (curr_task->status == TASK_IDLE)
stptr += KERNEL_STACK_SIZE - 0x10;
else
stptr += DEFAULT_STACK_SIZE - 0x10;
stptr = (stptr + DEFAULT_STACK_SIZE - 1) & ~0x1F;
set_per_core(kernel_stack, stptr);
tss_set_rsp0(stptr);
@ -151,7 +151,7 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg, uint32_t cor
* and not for HW-task-switching is setting up a stack and not a TSS.
* This is the stack which will be activated and popped off for iret later.
*/
stack = (size_t*) (((size_t) task->stack + DEFAULT_STACK_SIZE - 0x10) & ~0xF); // => stack is 16byte aligned
stack = (size_t*) (((size_t) task->stack + DEFAULT_STACK_SIZE - 1) & ~0x1F); // => stack is 16byte aligned
/* Only marker for debugging purposes, ... */
*stack-- = 0xDEADBEEF;

View file

@ -121,7 +121,7 @@ int timer_wait(unsigned int ticks)
if (per_core(timer_ticks) >= eticks)
break;
HALT;
PAUSE;
}
} else if (per_core(timer_ticks) < eticks) {
check_workqueues();

View file

@ -87,6 +87,8 @@ extern int32_t possible_isles;
extern uint32_t boot_processor;
extern int libc_sd;
uint32_t idle_poll = 1;
islelock_t* rcce_lock = NULL;
rcce_mpb_t* rcce_mpb = NULL;
@ -227,7 +229,7 @@ int smp_main(void)
while(1) {
check_workqueues();
if (libc_sd >= 0)
if (idle_poll)
PAUSE;
else
HALT;
@ -478,7 +480,7 @@ int hermit_main(void)
while(1) {
check_workqueues();
if (libc_sd >= 0)
if (idle_poll)
PAUSE;
else
HALT;

View file

@ -48,6 +48,7 @@ static spinlock_t lwip_lock = SPINLOCK_INIT;
extern int32_t isle;
extern int32_t possible_isles;
extern int libc_sd;
extern uint32_t idle_poll;
tid_t sys_getpid(void)
{
@ -90,6 +91,7 @@ void NORETURN sys_exit(int arg)
lwip_close(libc_sd);
libc_sd = -1;
idle_poll = 0;
}
do_exit(arg);