From ebe41f1d460f1fa86fb63db6342b7e2629b57bf8 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 25 Sep 2016 22:59:57 +0200 Subject: [PATCH] use the CPU brand to determine the frequency => reduce the boot time --- hermit/arch/x86/kernel/processor.c | 61 ++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/hermit/arch/x86/kernel/processor.c b/hermit/arch/x86/kernel/processor.c index 9a132074c..d25e6ea61 100644 --- a/hermit/arch/x86/kernel/processor.c +++ b/hermit/arch/x86/kernel/processor.c @@ -166,6 +166,63 @@ static void fpu_init_xsave(union fpu_state* fpu) xs->fxsave.mxcsr = 0x1f80; } +// Try to determine the frequency from the CPU brand. +// Code is derived from the manual "Intel Processor +// Identification and the CPUID Instruction". +static uint32_t get_frequency_from_brand(void) +{ + char brand[4*3*sizeof(uint32_t)+1]; + uint32_t eax = 0, ebx = 0; + uint32_t ecx = 0, edx = 0; + uint32_t index, multiplier = 0; + uint32_t* bint = (uint32_t*) brand; + + memset(brand, 0x00, sizeof(brand)); + + cpuid(0x80000000, &eax, &ebx, &ecx, &edx); + if (eax >= 0x80000004) + { + cpuid(0x80000002, bint+0, bint+1, bint+2, bint+3); + cpuid(0x80000003, bint+4, bint+5, bint+6, bint+7); + cpuid(0x80000004, bint+8, bint+9, bint+10, bint+11); + kprintf("Processor: %s\n", brand); + + for(index=0; index 0) { + uint32_t freq; + + // Compute frequency (in MHz) from brand string + if (brand[index-3] == '.') { // If format is “x.xx” + freq = (uint32_t)(brand[index-4] - '0') * multiplier; + freq += (uint32_t)(brand[index-2] - '0') * (multiplier / 10); + freq += (uint32_t)(brand[index-1] - '0') * (multiplier / 100); + } else { // If format is xxxx + freq = (uint32_t)(brand[index-4] - '0') * 1000; + freq += (uint32_t)(brand[index-3] - '0') * 100; + freq += (uint32_t)(brand[index-2] - '0') * 10; + freq += (uint32_t)(brand[index-1] - '0'); + freq *= multiplier; + } + + return freq; + } + } + } + + return 0; +} + uint32_t detect_cpu_frequency(void) { uint64_t start, end, diff; @@ -174,6 +231,10 @@ uint32_t detect_cpu_frequency(void) if (BUILTIN_EXPECT(cpu_freq > 0, 0)) return cpu_freq; + cpu_freq = get_frequency_from_brand(); + if (cpu_freq > 0) + return cpu_freq; + old = get_clock_tick(); /* wait for the next time slice */