3 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
12 #include <hw/cpu/cpu.h>
13 #include <hw/dos/dos.h>
14 #include <hw/dos/doswin.h>
15 #include <hw/flatreal/flatreal.h>
17 #include <hw/cpu/apiclib.h>
19 unsigned char apic_flags = 0;
20 uint32_t apic_base = 0;
21 const char* apic_error_str = NULL;
24 apic_flags = 0; /* to permit re-probing */
28 if (apic_flags == 0) {
31 /* FIXME: Some say the APIC-like interface appeared in the late 486 era, though as a separate chip,
32 * unlike the Pentium and later that put the APIC on-chip. How do we detect those? */
33 apic_flags = APIC_FLAG_PROBED;
36 if (cpu_basic_level < CPU_586) {
37 apic_error_str = "APIC support requires at least a 586/Pentium class system";
41 if (windows_mode >= WINDOWS_STANDARD) {
42 apic_error_str = "I will not attempt to play with the APIC from within Windows";
43 apic_flags |= APIC_FLAG_CANT_DETECT;
47 apic_error_str = "I will not attempt to play with the APIC from virtual 8086 mode";
48 apic_flags |= APIC_FLAG_CANT_DETECT;
51 if (!(cpu_flags & CPU_FLAG_CPUID)) {
52 apic_error_str = "APIC detection requires CPUID";
55 if (!(cpu_cpuid_features.a.raw[2/*EDX*/] & (1UL << 9UL))) {
56 apic_error_str = "CPU does not have on-chip APIC";
59 if (!(cpu_cpuid_features.a.raw[2/*EDX*/] & (1UL << 5UL))) {
60 apic_error_str = "CPU does have on-chip APIC but no support for RDMSR/WRMSR";
64 reg = cpu_rdmsr(0x0000001B); /* hopefully, we do not crash */
65 apic_base = (unsigned long)(reg & 0xFFFFF000UL);
66 apic_flags |= APIC_FLAG_PRESENT;
67 apic_flags |= (reg & (1UL << 11UL)) ? APIC_FLAG_GLOBAL_ENABLE : 0;
68 apic_flags |= (reg & (1UL << 8UL)) ? APIC_FLAG_PROBE_ON_BOOT_CPU : 0;
71 return (apic_flags & APIC_FLAG_PRESENT)?1:0;