15af32e75SAxel Dörfler /* 2db905187SIngo Weinhold * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 35af32e75SAxel Dörfler * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 45af32e75SAxel Dörfler * Distributed under the terms of the MIT License. 55af32e75SAxel Dörfler */ 65af32e75SAxel Dörfler 75af32e75SAxel Dörfler 85af32e75SAxel Dörfler #include <OS.h> 97b4d924fSAndrej Antunovikj 107b4d924fSAndrej Antunovikj #include <boot/arch/x86/arch_cpu.h> 115af32e75SAxel Dörfler #include <boot/kernel_args.h> 127b4d924fSAndrej Antunovikj #include <boot/platform.h> 135af32e75SAxel Dörfler #include <boot/stage2.h> 147b4d924fSAndrej Antunovikj #include <boot/stdio.h> 157b4d924fSAndrej Antunovikj 167b4d924fSAndrej Antunovikj #include <arch/x86/arch_cpu.h> 175af32e75SAxel Dörfler #include <arch_kernel.h> 18484c80abSAxel Dörfler #include <arch_system_info.h> 195af32e75SAxel Dörfler 205af32e75SAxel Dörfler #include <string.h> 215af32e75SAxel Dörfler 225af32e75SAxel Dörfler 235af32e75SAxel Dörfler //#define TRACE_CPU 245af32e75SAxel Dörfler #ifdef TRACE_CPU 255af32e75SAxel Dörfler # define TRACE(x) dprintf x 265af32e75SAxel Dörfler #else 275af32e75SAxel Dörfler # define TRACE(x) ; 285af32e75SAxel Dörfler #endif 295af32e75SAxel Dörfler 305af32e75SAxel Dörfler 31484c80abSAxel Dörfler #define CPUID_EFLAGS (1UL << 21) 32484c80abSAxel Dörfler #define RDTSC_FEATURE (1UL << 4) 33484c80abSAxel Dörfler 345af32e75SAxel Dörfler 355af32e75SAxel Dörfler static status_t check_cpu_features()365af32e75SAxel Dörflercheck_cpu_features() 375af32e75SAxel Dörfler { 38484c80abSAxel Dörfler // check the eflags register to see if the cpuid instruction exists 39484c80abSAxel Dörfler if ((get_eflags() & CPUID_EFLAGS) == 0) { 40484c80abSAxel Dörfler // it's not set yet, but maybe we can set it manually 41484c80abSAxel Dörfler set_eflags(get_eflags() | CPUID_EFLAGS); 42484c80abSAxel Dörfler if ((get_eflags() & CPUID_EFLAGS) == 0) 43484c80abSAxel Dörfler return B_ERROR; 44484c80abSAxel Dörfler } 45484c80abSAxel Dörfler 46484c80abSAxel Dörfler cpuid_info info; 474110b730SPawel Dziepak if (get_current_cpuid(&info, 1, 0) != B_OK) 48484c80abSAxel Dörfler return B_ERROR; 49484c80abSAxel Dörfler 50484c80abSAxel Dörfler if ((info.eax_1.features & RDTSC_FEATURE) == 0) { 51484c80abSAxel Dörfler // we currently require RDTSC 52484c80abSAxel Dörfler return B_ERROR; 53484c80abSAxel Dörfler } 54484c80abSAxel Dörfler 555af32e75SAxel Dörfler return B_OK; 565af32e75SAxel Dörfler } 575af32e75SAxel Dörfler 585af32e75SAxel Dörfler 595af32e75SAxel Dörfler // #pragma mark - 605af32e75SAxel Dörfler 615af32e75SAxel Dörfler 62d2986cb6SAlexander von Gluck IV void cpu_init()635af32e75SAxel Dörflercpu_init() 645af32e75SAxel Dörfler { 655af32e75SAxel Dörfler if (check_cpu_features() != B_OK) 665af32e75SAxel Dörfler panic("You need a Pentium or higher in order to boot!\n"); 675af32e75SAxel Dörfler 68*bb2808d6SAugustin Cavalier determine_cpu_conversion_factor(0); 695af32e75SAxel Dörfler 705af32e75SAxel Dörfler gKernelArgs.num_cpus = 1; 715af32e75SAxel Dörfler // this will eventually be corrected later on 725af32e75SAxel Dörfler } 7311f8b65aSJérôme Duval 7411f8b65aSJérôme Duval 7511f8b65aSJérôme Duval extern "C" void platform_load_ucode(BootVolume & volume)7611f8b65aSJérôme Duvalplatform_load_ucode(BootVolume& volume) 7711f8b65aSJérôme Duval { 7889fd39f4SAlexander von Gluck IV arch_ucode_load(volume); 7911f8b65aSJérôme Duval } 80