On Wed, Jan 25, 2012 at 06:45:28PM +0100, Rudolf Marek wrote:
Hi all
As requested here is the first patch.
How about this patch instead?
-Kevin
commit c2228f401c13e0b300c6b1fcc43cc9097f47bb43 Author: Kevin O'Connor kevin@koconnor.net Date: Sun Jan 29 13:30:56 2012 -0500
Detect CPUID instruction before using it.
Enable SeaBIOS to work on 386/486 machines that don't have CPUID instruction.
Based on patch by Rudolf Marek.
Signed-off-by: Rudolf Marek r.marek@assembler.cz Signed-off-by: Kevin O'Connor kevin@koconnor.net
diff --git a/src/bregs.h b/src/bregs.h index f026fa8..577effc 100644 --- a/src/bregs.h +++ b/src/bregs.h @@ -11,6 +11,7 @@ #define F_CF (1<<0) #define F_ZF (1<<6) #define F_IF (1<<9) +#define F_ID (1<<21)
// CR0 flags #define CR0_PG (1<<31) // Paging diff --git a/src/mptable.c b/src/mptable.c index 103f462..3422212 100644 --- a/src/mptable.c +++ b/src/mptable.c @@ -35,7 +35,7 @@ mptable_init(void)
// Detect cpu info u32 cpuid_signature, ebx, ecx, cpuid_features; - cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features); + get_cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features); if (! cpuid_signature) { // Use default values. cpuid_signature = 0x600; diff --git a/src/mtrr.c b/src/mtrr.c index 0548043..b6a8427 100644 --- a/src/mtrr.c +++ b/src/mtrr.c @@ -37,7 +37,7 @@ void mtrr_setup(void) return;
u32 eax, ebx, ecx, edx, cpuid_features; - cpuid(1, &eax, &ebx, &ecx, &cpuid_features); + get_cpuid(1, &eax, &ebx, &ecx, &cpuid_features); if (!(cpuid_features & CPUID_MTRR)) return; if (!(cpuid_features & CPUID_MSR)) @@ -82,11 +82,11 @@ void mtrr_setup(void)
// Set variable MTRRs int phys_bits = 36; - cpuid(0x80000000u, &eax, &ebx, &ecx, &edx); + get_cpuid(0x80000000u, &eax, &ebx, &ecx, &edx); if (eax >= 0x80000008) { - /* Get physical bits from leaf 0x80000008 (if available) */ - cpuid(0x80000008u, &eax, &ebx, &ecx, &edx); - phys_bits = eax & 0xff; + /* Get physical bits from leaf 0x80000008 (if available) */ + get_cpuid(0x80000008u, &eax, &ebx, &ecx, &edx); + phys_bits = eax & 0xff; } u64 phys_mask = ((1ull << phys_bits) - 1); for (i=0; i<vcnt; i++) { diff --git a/src/paravirt.h b/src/paravirt.h index 4a370a0..4014943 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -11,10 +11,12 @@
static inline int kvm_para_available(void) { + if (CONFIG_COREBOOT) + return 0; unsigned int eax, ebx, ecx, edx; char signature[13];
- cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); + get_cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); memcpy(signature + 0, &ebx, 4); memcpy(signature + 4, &ecx, 4); memcpy(signature + 8, &edx, 4); diff --git a/src/smbios.c b/src/smbios.c index fe1e183..9c8df98 100644 --- a/src/smbios.c +++ b/src/smbios.c @@ -255,7 +255,7 @@ smbios_init_type_4(void *start, unsigned int cpu_number) if (!qemu_cfg_smbios_load_field(4, offsetof(struct smbios_type_4, processor_id), p->processor_id)) { u32 cpuid_signature, ebx, ecx, cpuid_features; - cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features); + get_cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features); p->processor_id[0] = cpuid_signature; p->processor_id[1] = cpuid_features; } diff --git a/src/smp.c b/src/smp.c index 8c077a1..e36f960 100644 --- a/src/smp.c +++ b/src/smp.c @@ -73,7 +73,7 @@ smp_probe(void) { ASSERT32FLAT(); u32 eax, ebx, ecx, cpuid_features; - cpuid(1, &eax, &ebx, &ecx, &cpuid_features); + get_cpuid(1, &eax, &ebx, &ecx, &cpuid_features); if (eax < 1 || !(cpuid_features & CPUID_APIC)) { // No apic - only the main cpu is present. dprintf(1, "No apic - only the main cpu is present.\n"); diff --git a/src/util.c b/src/util.c index ed73d63..7141f5d 100644 --- a/src/util.c +++ b/src/util.c @@ -8,6 +8,22 @@ #include "bregs.h" // struct bregs #include "config.h" // BUILD_STACK_ADDR
+void +get_cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) +{ + // Check for cpu id + u32 origflags = save_flags(); + restore_flags(origflags ^ F_ID); + u32 newflags = save_flags(); + restore_flags(origflags); + + if (((origflags ^ newflags) & F_ID) != F_ID) + // no cpuid + *eax = *ebx = *ecx = *edx = 0; + else + cpuid(index, eax, ebx, ecx, edx); +} +
/**************************************************************** * 16bit calls diff --git a/src/util.h b/src/util.h index eecba8b..a69949d 100644 --- a/src/util.h +++ b/src/util.h @@ -18,15 +18,14 @@ static inline void irq_enable(void) asm volatile("sti": : :"memory"); }
-static inline unsigned long irq_save(void) +static inline u32 save_flags(void) { - unsigned long flags; - asm volatile("pushfl ; popl %0" : "=g" (flags): :"memory"); - irq_disable(); + u32 flags; + asm("pushfl ; popl %0" : "=rm" (flags)); return flags; }
-static inline void irq_restore(unsigned long flags) +static inline void restore_flags(u32 flags) { asm volatile("pushl %0 ; popfl" : : "g" (flags) : "memory", "cc"); } @@ -196,6 +195,7 @@ struct descloc_s { } PACKED;
// util.c +void get_cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); struct bregs; inline void call16(struct bregs *callregs); inline void call16big(struct bregs *callregs); diff --git a/src/xen.c b/src/xen.c index 4072793..5f4abdb 100644 --- a/src/xen.c +++ b/src/xen.c @@ -55,7 +55,7 @@ void xen_probe(void) return;
for (base = 0x40000000; base < 0x40010000; base += 0x100) { - cpuid(base, &eax, &ebx, &ecx, &edx); + get_cpuid(base, &eax, &ebx, &ecx, &edx); memcpy(signature + 0, &ebx, 4); memcpy(signature + 4, &ecx, 4); memcpy(signature + 8, &edx, 4); @@ -88,7 +88,7 @@ void xen_init_hypercalls(void) if (!usingXen()) return;
- cpuid(xen_cpuid_base + 2, &eax, &ebx, &ecx, &edx); + get_cpuid(xen_cpuid_base + 2, &eax, &ebx, &ecx, &edx);
xen_hypercall_page = (unsigned long)memalign_high(PAGE_SIZE, eax*PAGE_SIZE); if (!xen_hypercall_page) @@ -99,7 +99,7 @@ void xen_init_hypercalls(void) wrmsr(ebx, xen_hypercall_page + (i << 12) + i);
/* Print version information. */ - cpuid(xen_cpuid_base + 1, &eax, &ebx, &ecx, &edx); + get_cpuid(xen_cpuid_base + 1, &eax, &ebx, &ecx, &edx); hypercall_xen_version(XENVER_extraversion, extraversion); dprintf(1, "Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion); }