[syslinux:lwip] Create a sysappend string with some very minimal CPU information

syslinux-bot for H. Peter Anvin hpa at zytor.com
Wed Apr 27 21:36:34 PDT 2011


Commit-ID:  9f8e66b5fe2b0106c00453e82094bd8f1cc7762e
Gitweb:     http://syslinux.zytor.com/commit/9f8e66b5fe2b0106c00453e82094bd8f1cc7762e
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Wed, 27 Apr 2011 21:32:53 -0700
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Wed, 27 Apr 2011 21:32:53 -0700

Create a sysappend string with some very minimal CPU information

Doing a full system manifest is obviously not possible, but we can
include some very very basic CPU information.

Signed-off-by: H. Peter Anvin <hpa at zytor.com>


---
 com32/include/syslinux/sysappend.h |    1 +
 core/dmi.c                         |   55 ++++++++++++++++++++++++++++++++++++
 doc/syslinux.txt                   |   44 ++++++++++++++++++++--------
 3 files changed, 87 insertions(+), 13 deletions(-)

diff --git a/com32/include/syslinux/sysappend.h b/com32/include/syslinux/sysappend.h
index 322456b..f243eab 100644
--- a/com32/include/syslinux/sysappend.h
+++ b/com32/include/syslinux/sysappend.h
@@ -38,6 +38,7 @@ enum syslinux_sysappend {
     SYSAPPEND_IP,		/* PXELINUX: ip= address */
     SYSAPPEND_BOOTIF,		/* PXELINUX: BOOTIF= address */
     SYSAPPEND_SYSUUID,		/* System UUID from PXE or DMI */
+    SYSAPPEND_CPU,		/* CPU features */
     SYSAPPEND_SYSVENDOR,	/* System or MB vendor from DMI */
     SYSAPPEND_SYSPRODUCT,	/* System or MB product from DMI */
     SYSAPPEND_SYSVERSION,	/* System or MB version from DMI */
diff --git a/core/dmi.c b/core/dmi.c
index 9589ac8..d500d56 100644
--- a/core/dmi.c
+++ b/core/dmi.c
@@ -31,6 +31,8 @@
 
 #include <string.h>
 #include <stdio.h>
+#include <sys/bitops.h>
+#include <sys/cpu.h>
 #include <syslinux/sysappend.h>
 #include "core.h"
 
@@ -308,10 +310,63 @@ static void sysappend_set_sysff(const uint8_t *type)
     sysappend_strings[SYSAPPEND_SYSFF] = sysff_str;
 }
 
+struct cpuflag {
+    uint8_t bit;
+    char flag;
+};
+
+static void sysappend_set_cpu(void)
+{
+    static char cpu_str[6+6] = "CPU=";
+    char *p = cpu_str + 4;
+    static const struct cpuflag cpuflags[] = {
+	{ 0*32+ 6, 'P' }, /* PAE */
+	{ 1*32+ 5, 'V' }, /* VMX */
+	{ 1*32+ 6, 'T' }, /* SMX (TXT) */
+	{ 2*32+20, 'X' }, /* XD/NX */
+	{ 2*32+29, 'L' }, /* Long mode (x86-64) */
+	{ 3*32+ 2, 'S' }, /* SVM */
+	{ 0, 0 }
+    };
+    const struct cpuflag *cf;
+
+    /* Not technically from DMI, but it fit here... */
+
+    if (!cpu_has_eflag(EFLAGS_ID)) {
+	/* No CPUID */
+	*p++ = cpu_has_eflag(EFLAGS_AC) ? '4' : '3';
+    } else {
+	uint32_t flags[4], eax, ebx, family;
+	uint32_t std_level, ext_level;
+
+	cpuid(1, &eax, &ebx, &flags[1], &flags[0]);
+	family = (eax & 0x0ff00f00) >> 8;
+	*p++ = family >= 6 ? '6' : family + '0';
+	
+	ext_level = cpuid_eax(0x80000000);
+	if (ext_level >= 0x80000001 && ext_level <= 0x8000ffff) {
+	    cpuid(0x80000001, &eax, &ebx, &flags[3], &flags[2]);
+	} else {
+	    flags[2] = flags[3] = 0;
+	}
+
+	for (cf = cpuflags; cf->flag; cf++) {
+	    if (test_bit(cf->bit, flags))
+		*p++ = cf->flag;
+	}
+    }
+
+    *p = '\0';
+
+    sysappend_strings[SYSAPPEND_CPU] = cpu_str;
+}
+
 void dmi_init(void)
 {
     const struct sysappend_dmi_strings *ds;
 
+    sysappend_set_cpu();
+
     dmi_find_header();
     if (!dmi)
 	return;
diff --git a/doc/syslinux.txt b/doc/syslinux.txt
index d7efd1c..31687ae 100644
--- a/doc/syslinux.txt
+++ b/doc/syslinux.txt
@@ -197,24 +197,42 @@ IPAPPEND bitmask
 	This may not be available if no valid UUID is found on the
 	system.
 
+	8: indicate the CPU family and certain particularly
+	significant CPU feature bits:
+
+		CPU=<family><features>
+
+	The <family> is a single digit from 3 (i386) to 6 (i686 or
+	higher.)  The following CPU feature are currently reported;
+	additional flags may be added in the future:
+
+		P	Physical Address Extension (PAE)
+		V	Intel Virtualization Technology (VT/VMX)
+		T	Intel Trusted Exection Technology (TXT/SMX)
+		X	Execution Disable (XD/NX)
+		L	Long Mode (x86-64)
+		S	AMD SMX virtualization
+	
+	This was added in 4.10.
+
 	The following strings are derived from DMI/SMBIOS information
 	if available; these are all new in version 4.10:
 	
 	Bit	String		Significance
 	-------------------------------------------------------------
-	0x0008	SYSVENDOR=	System vendor name
-	0x0010	SYSPRODUCT=	System product name
-	0x0020	SYSVERSION=	System version
-	0x0040	SYSSERIAL=	System serial number
-	0x0080	SYSSKU=		System SKU
-	0x0100	SYSFAMILY=	System family
-	0x0200	MBVENDOR=	Motherboard vendor name
-	0x0400	MBVERSION=	Motherboard version
-	0x0800	MBSERIAL=	Motherboard serial number
-	0x1000	MBASSET=	Motherboard asset tag
-	0x2000  BIOSVENDOR=	BIOS vendor name
-	0x4000	BIOSVERSION=	BIOS version
-	0x8000	SYSFF=		System form factor
+	0x00010	SYSVENDOR=	System vendor name
+	0x00020	SYSPRODUCT=	System product name
+	0x00040	SYSVERSION=	System version
+	0x00080	SYSSERIAL=	System serial number
+	0x00100	SYSSKU=		System SKU
+	0x00200	SYSFAMILY=	System family
+	0x00400	MBVENDOR=	Motherboard vendor name
+	0x00800	MBVERSION=	Motherboard version
+	0x01000	MBSERIAL=	Motherboard serial number
+	0x02000	MBASSET=	Motherboard asset tag
+	0x04000 BIOSVENDOR=	BIOS vendor name
+	0x08000	BIOSVERSION=	BIOS version
+	0x10000	SYSFF=		System form factor
 
 	If these strings contain whitespace they it is replaced with
 	underscores (_).



More information about the Syslinux-commits mailing list