Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Feb 2009 14:49:20 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-6@freebsd.org
Subject:   svn commit: r188517 - in stable/6/sys: . boot/i386/libi386 contrib/pf dev/cxgb
Message-ID:  <200902121449.n1CEnKFK058700@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Thu Feb 12 14:49:20 2009
New Revision: 188517
URL: http://svn.freebsd.org/changeset/base/188517

Log:
  MFC: Use CPUID to see if the current CPU supports long mode when attemping
  to boot an amd64 kernel.

Modified:
  stable/6/sys/   (props changed)
  stable/6/sys/boot/i386/libi386/bootinfo64.c
  stable/6/sys/contrib/pf/   (props changed)
  stable/6/sys/dev/cxgb/   (props changed)

Modified: stable/6/sys/boot/i386/libi386/bootinfo64.c
==============================================================================
--- stable/6/sys/boot/i386/libi386/bootinfo64.c	Thu Feb 12 14:44:15 2009	(r188516)
+++ stable/6/sys/boot/i386/libi386/bootinfo64.c	Thu Feb 12 14:49:20 2009	(r188517)
@@ -32,6 +32,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/reboot.h>
 #include <sys/linker.h>
 #include <machine/bootinfo.h>
+#include <machine/cpufunc.h>
+#include <machine/psl.h>
+#include <machine/specialreg.h>
 #include "bootstrap.h"
 #include "libi386.h"
 #include "btxv86.h"
@@ -124,7 +127,45 @@ bi_copymodules64(vm_offset_t addr)
 }
 
 /*
- * Load the information expected by an i386 kernel.
+ * Check to see if this CPU supports long mode.
+ */
+static int
+bi_checkcpu(void)
+{
+    char *cpu_vendor;
+    int vendor[3];
+    int eflags, regs[4];
+
+    /* Check for presence of "cpuid". */
+    eflags = read_eflags();
+    write_eflags(eflags ^ PSL_ID);
+    if (!((eflags ^ read_eflags()) & PSL_ID))
+	return (0);
+
+    /* Fetch the vendor string. */
+    do_cpuid(0, regs);
+    vendor[0] = regs[1];
+    vendor[1] = regs[3];
+    vendor[2] = regs[2];
+    cpu_vendor = (char *)vendor;
+
+    /* Check for vendors that support AMD features. */
+    if (strncmp(cpu_vendor, "GenuineIntel", 12) != 0 &&
+	strncmp(cpu_vendor, "AuthenticAMD", 12) != 0)
+	return (0);
+
+    /* Has to support AMD features. */
+    do_cpuid(0x80000000, regs);
+    if (!(regs[0] >= 0x80000001))
+	return (0);
+
+    /* Check for long mode. */
+    do_cpuid(0x80000001, regs);
+    return (regs[3] & AMDID_LM);
+}
+
+/*
+ * Load the information expected by an amd64 kernel.
  *
  * - The 'boothowto' argument is constructed
  * - The 'bootdev' argument is constructed
@@ -147,6 +188,11 @@ bi_load64(char *args, vm_offset_t *modul
     char			*kernelname;
     const char			*kernelpath;
 
+    if (!bi_checkcpu()) {
+	printf("CPU doesn't support long mode\n");
+	return (EINVAL);
+    }
+
     howto = bi_getboothowto(args);
 
     /* 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902121449.n1CEnKFK058700>