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:
parent
2c200558f1
commit
6514e2d8fd
7 changed files with 137 additions and 10 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue