movl 24(%edx), %esi
movl 28(%edx), %edx
+ /*
+ Via C3 CPUs have cache coherence problems, so we need to call
+ wbinvd at these 2 points. As wbinvd slows down boot, don't do
+ it on non-VIA. 9090 is nop nop. */
+VARIABLE(grub_bios_via_workaround1)
+ .byte 0x90, 0x90
+
PROT_TO_REAL
.code16
pushf
movw %ax, LOCAL(bios_register_es)
popf
+
+VARIABLE(grub_bios_via_workaround2)
+ .byte 0x90, 0x90
+
REAL_TO_PROT
.code32
#include <grub/env.h>
#include <grub/cache.h>
#include <grub/time.h>
+#include <grub/cpu/cpuid.h>
#include <grub/cpu/tsc.h>
#include <grub/machine/time.h>
return 0;
}
+extern grub_uint16_t grub_bios_via_workaround1, grub_bios_via_workaround2;
+
+/* Via needs additional wbinvd. */
+static void
+grub_via_workaround_init (void)
+{
+ grub_uint32_t manufacturer[3], max_cpuid;
+ if (! grub_cpu_is_cpuid_supported ())
+ return;
+
+ grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]);
+
+ if (grub_memcmp (manufacturer, "CentaurHauls", 12) != 0)
+ return;
+
+ grub_bios_via_workaround1 = 0x090f;
+ grub_bios_via_workaround2 = 0x090f;
+ asm volatile ("wbinvd");
+}
+
void
grub_machine_init (void)
{
#endif
grub_addr_t modend;
+ /* This has to happen before any BIOS calls. */
+ grub_via_workaround_init ();
+
grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start);
/* Initialize the console as early as possible. */