xref: /haiku/src/system/boot/platform/bios_ia32/cpu.cpp (revision bb2808d6156e8e9e2650a62b667a67bee248d52c)
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örfler check_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örfler cpu_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 Duval platform_load_ucode(BootVolume& volume)
7711f8b65aSJérôme Duval {
7889fd39f4SAlexander von Gluck IV 	arch_ucode_load(volume);
7911f8b65aSJérôme Duval }
80