[coreboot-gerrit] Patch set updated for coreboot: util/intelmetool: Add bootguard information dump support

Philipp Deppenwiese (zaolin.daisuki@googlemail.com) gerrit at coreboot.org
Fri Aug 26 19:55:43 CEST 2016


Philipp Deppenwiese (zaolin.daisuki at googlemail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16328

-gerrit

commit 3e415821d13b1d89e14603b95aee70efb5c376a2
Author: Philipp Deppenwiese <zaolin at das-labor.org>
Date:   Fri Aug 26 02:10:51 2016 +0200

    util/intelmetool: Add bootguard information dump support
    
    With this implementation it's possible to detect the state
    of bootguard in intel based systems. Currently it's WIP and
    in a testphase. Handle it with care!
    
    Change-Id: Ifeec8e20fa8efc35d7db4c6a84be1f118dccfc4a
    Signed-off-by: Philipp Deppenwiese <zaolin at das-labor.org>
---
 util/intelmetool/Makefile      |   2 +-
 util/intelmetool/intelmetool.c | 213 ++++++++++++++++++++++++++++-------------
 util/intelmetool/intelmetool.h |   9 +-
 util/intelmetool/me.c          |  14 +--
 util/intelmetool/me.h          |   2 +
 util/intelmetool/mmap.c        |   4 -
 util/intelmetool/msr.c         |  78 +++++++++++++++
 util/intelmetool/msr.h         |  43 +++++++++
 8 files changed, 282 insertions(+), 83 deletions(-)

diff --git a/util/intelmetool/Makefile b/util/intelmetool/Makefile
index 4461f86..4ea5c0f 100644
--- a/util/intelmetool/Makefile
+++ b/util/intelmetool/Makefile
@@ -20,7 +20,7 @@ PREFIX  ?= /usr/local
 CFLAGS  ?= -O0 -g -Wall -W -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-sign-compare -Wno-unused-function
 LDFLAGS += -lpci -lz
 
-OBJS = intelmetool.o me.o me_status.o mmap.o
+OBJS = intelmetool.o me.o me_status.o mmap.o msr.o
 
 OS_ARCH	= $(shell uname)
 ifeq ($(OS_ARCH), Darwin)
diff --git a/util/intelmetool/intelmetool.c b/util/intelmetool/intelmetool.c
index aec0715..8208142 100644
--- a/util/intelmetool/intelmetool.c
+++ b/util/intelmetool/intelmetool.c
@@ -16,6 +16,8 @@
 #include <stdlib.h>
 #include <getopt.h>
 #include <unistd.h>
+#include <string.h>
+#include <cpuid.h>
 
 #ifdef __NetBSD__
 #include <machine/sysarch.h>
@@ -23,17 +25,22 @@
 
 #include "me.h"
 #include "mmap.h"
+#include "msr.h"
 #include "intelmetool.h"
 
-#define FD2 0x3428
-#define ME_COMMAND_DELAY 10000
-
 extern int fd_mem;
 int debug = 0;
 
 static uint32_t fd2 = 0;
 static const int size = 0x4000;
 static volatile uint8_t *rcba;
+static char cpu_id[CPU_ID_SIZE] = { 0 };
+
+void print_cap(const char *name, int state)
+{
+	printf("ME Capability: %-30s : %s\n",
+	       name, state ? CRED "ON" RESET : CGRN "OFF" RESET);
+}
 
 static void dumpmem(uint8_t *phys, uint32_t size)
 {
@@ -72,6 +79,16 @@ static void rehide_me() {
 	}
 }
 
+static void get_cpu_id(char *id) {
+	cpu_t cpu;
+	unsigned int level = 0;
+	unsigned int eax = 0;
+
+	__get_cpuid(level, &eax, &cpu.ebx, &cpu.ecx, &cpu.edx);
+
+	memcpy(id, (char*)&cpu, CPU_ID_SIZE);
+}
+
 /* You need >4GB total ram, in kernel cmdline, use 'mem=1000m'
  * then this code will clone to absolute memory address 0xe0000000
  * which can be read using a mmap tool at that offset.
@@ -80,10 +97,14 @@ static void rehide_me() {
  */
 static void dump_me_memory() {
 	uint32_t me_clone = 0x60000000;
-	uint8_t *dump;
+	void *dump;
 
 	dump = map_physical_exact(me_clone, me_clone, 0x2000000);
-	zeroit(dump, 0x2000000);
+	if(!dump) {
+		printf("ME physical memory can't be mapped!! Take a look at DMESG log.\n");
+		return;
+	}
+	zeroit((uint8_t*)dump, 0x2000000);
 	printf("Send magic command for memory clone\n");
 
 	mei_reset();
@@ -95,7 +116,7 @@ static void dump_me_memory() {
 		printf("Wait a second...");
 		usleep(ME_COMMAND_DELAY);
 		printf("done\n\nHere are the first bytes:\n");
-		dumpmemfile(dump, 0x2000000);
+		dumpmemfile((uint8_t*)dump, 0x2000000);
 		//printf("Try reading 0x%zx with other mmap tool...\n"
 		//	"Press enter to quit, you only get one chance to run this tool before reboot required for some reason\n", me_clone);
 		while (getc(stdin) != '\n') {};
@@ -103,10 +124,9 @@ static void dump_me_memory() {
 	}
 }
 
-static int pci_platform_scan() {
+static int pci_platform_scan(char* msg) {
 	struct pci_access *pacc;
 	struct pci_dev *dev;
-	char namebuf[1024], *name;
 
 	pacc = pci_alloc();
 	pacc->method = PCI_ACCESS_I386_TYPE1;
@@ -116,38 +136,28 @@ static int pci_platform_scan() {
 
 	for (dev=pacc->devices; dev; dev=dev->next) {
 		pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_SIZES | PCI_FILL_CLASS);
-		name = pci_lookup_name(pacc, namebuf, sizeof(namebuf),
-			PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id);
-		if (dev->vendor_id == 0x8086) {
+		if (dev->vendor_id == INTEL_PLATFORM_VENDOR_ID) {
 			if (PCI_DEV_HAS_ME_DISABLE(dev->device_id)) {
-				printf(CGRN "Good news, you have a `%s` so ME is present but can be disabled, continuing...\n\n" RESET, name);
+				snprintf(msg, ME_MESSAGE_LEN, CGRN "Good news, your ME is present but can be disabled, continuing...\n\n" RESET);
 				break;
 			} else if (PCI_DEV_HAS_ME_DIFFICULT(dev->device_id)) {
-				printf(CRED "Bad news, you have a `%s` so you have ME hardware on board and you can't control or disable it, continuing...\n\n" RESET, name);
+				snprintf(msg, ME_MESSAGE_LEN, CRED "Bad news, you have ME hardware on board but you can't control or disable it, continuing...\n\n" RESET);
 				break;
 			} else if (PCI_DEV_CAN_DISABLE_ME_IF_PRESENT(dev->device_id)) {
-				printf(CYEL "Not sure if ME hardware is present because you have a `%s`, but it is possible to disable it if you do, continuing...\n\n" RESET, name);
+				snprintf(msg, ME_MESSAGE_LEN, CYEL "Not sure if ME hardware is present, but it is possible to disable it if you do, continuing...\n\n" RESET);
 				break;
 			} else if (PCI_DEV_ME_NOT_SURE(dev->device_id)) {
-				printf(CYEL "Found `%s`. Not sure whether you have ME hardware, exiting\n\n" RESET, name);
-				pci_cleanup(pacc);
-				return 1;
+				snprintf(msg, ME_MESSAGE_LEN, CYEL "Not sure whether you have ME hardware, exiting\n\n" RESET);
 				break;
 			}
 		}
 	}
 
-	if (!PCI_DEV_HAS_ME_DISABLE(dev->device_id) &&
-	!PCI_DEV_HAS_ME_DIFFICULT(dev->device_id) &&
-	!PCI_DEV_CAN_DISABLE_ME_IF_PRESENT(dev->device_id) &&
-	!PCI_DEV_ME_NOT_SURE(dev->device_id)) {
-		printf(CCYN "ME is not present on your board or unkown\n\n" RESET);
-		pci_cleanup(pacc);
-		return 1;
+	if(!dev) {
+		snprintf(msg, ME_MESSAGE_LEN, CCYN "ME is not present on your board or unkown\n\n" RESET);
 	}
 
 	pci_cleanup(pacc);
-
 	return 0;
 }
 
@@ -166,7 +176,7 @@ static struct pci_dev *pci_me_interface_scan(char **name) {
 	for (dev=pacc->devices; dev; dev=dev->next) {
 		pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_SIZES | PCI_FILL_CLASS);
 		*name = pci_lookup_name(pacc, namebuf, sizeof(namebuf),
-			PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id);
+					PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id);
 		if (dev->vendor_id == 0x8086) {
 			if (PCI_DEV_HAS_SUPPORTED_ME(dev->device_id)) {
 				me = 1;
@@ -206,7 +216,12 @@ static int activate_me() {
 	pci_fill_info(sb, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_SIZES | PCI_FILL_CLASS);
 
 	rcba_phys = pci_read_long(sb, 0xf0) & 0xfffffffe;
-	rcba = map_physical(rcba_phys, size);
+	void* map = map_physical(rcba_phys, size);
+	if(!map) {
+		return 1;
+	} else {
+		rcba = (uint8_t*)map;
+	}
 
 	//printf("RCBA at 0x%08" PRIx32 "\n", (uint32_t)rcba_phys);
 	fd2 = *(uint32_t *)(rcba + FD2);
@@ -225,9 +240,9 @@ static int activate_me() {
 static void dump_me_info() {
 	struct pci_dev *dev;
 	uint32_t stat, stat2;
-	char *name;
+	char *name, msg[ME_MESSAGE_LEN] = { 0 };
 
-	if (pci_platform_scan()) {
+	if (pci_platform_scan(msg)) {
 		exit(1);
 	}
 
@@ -236,10 +251,9 @@ static void dump_me_info() {
 		exit(1);
 	}
 
-	if (activate_me()) {
-		exit(1);
-	}
+	activate_me();
 
+	printf("%s", msg);
 	printf("MEI found: [%x:%x] %s\n\n", dev->vendor_id, dev->device_id, name);
 	stat = pci_read_long(dev, 0x40);
 	printf("ME Status   : 0x%x\n", stat);
@@ -271,10 +285,62 @@ static void dump_me_info() {
 	munmap((void*)rcba, size);
 }
 
+static void dump_bootguard_info() {
+	struct pci_dev *dev;
+	uint32_t stat = 0;
+	char *name, msg[ME_MESSAGE_LEN] = { 0 };
+	uint64_t bootguard = 0;
+
+	if(msr_bootguard(&bootguard, debug) < 0) {
+		return;
+	}
+
+	pci_platform_scan(msg);
+	dev = pci_me_interface_scan(&name);
+	activate_me();
+
+	if(dev) {
+		stat = pci_read_long(dev, 0x40);
+	}
+
+	if(debug) {
+		printf("BootGuard MSR Output: 0x%" PRIx64 "\n", bootguard);
+		bootguard &= ~0xff;
+	}
+
+	if(BOOTGUARD_CAPABILITY(bootguard)) {
+		print_cap("BootGuard                                 ", 1);
+		if (dev && (stat & 0x10)) {
+			printf(CYEL "Your southbridge configuration is insecure!! BootGuard keys can be overwritten or wiped or you are in developer mode.\n" RESET);
+		}
+		switch(bootguard) {
+		case BOOTGUARD_DISABLED:
+			printf("ME Capability: BootGuard Mode                             : " CGRN "Disabled\n" RESET);
+			printf(CGRN "\nYour system is bootguard ready but your vendor disabled it. You can flash other firmware!\n" RESET);
+			break;
+		case BOOTGUARD_ENABLED_COMBI_MODE:
+			printf("ME Capability: Bootguard Mode                             : " CRED "Verified & Measured Boot\n" RESET);
+			printf(CRED "\nYou can't flash other firmware. Verified boot is enabled!\n" RESET);
+			break;
+		case BOOTGUARD_ENABLED_MEASUREMENT_MODE:
+			printf("ME Capability: Bootguard Mode                             : " CGRN "Measured Boot\n" RESET);
+			printf(CGRN "\nYour system is bootguard ready but only running the measured boot mode. You can flash other firmware!\n" RESET);
+			break;
+		case BOOTGUARD_ENABLED_VERIFIED_MODE:
+			printf("ME Capability: Bootguard Mode                             : " CRED "Verified Boot\n" RESET);
+			printf(CRED "\nYou can't flash other firmware. Verified boot is enabled!\n" RESET);
+			break;
+		}
+	} else {
+		print_cap("BootGuard                                 ", 0);
+		printf(CGRN "\nYour system isn't bootguard ready. You can flash other firmware!\n" RESET);
+	}
+}
+
 static void print_version(void)
 {
 	printf("intelmetool v%s -- ", INTELMETOOL_VERSION);
-	printf("Copyright (C) 2015 Damien Zammit\n\n");
+	printf("Copyright (C) 2016 Damien Zammit, Philipp Deppenwiese\n\n");
 	printf(
 		"This program is free software: you can redistribute it and/or modify\n"
 		"it under the terms of the GNU General Public License as published by\n"
@@ -287,13 +353,14 @@ static void print_version(void)
 
 static void print_usage(const char *name)
 {
-	printf("usage: %s [-vh?sd]\n", name);
+	printf("usage: %s [-vh?mdb]\n", name);
 	printf("\n"
-			 "   -v | --version:                   print the version\n"
-			 "   -h | --help:                      print this help\n\n"
-			 "   -s | --show:                      dump all me information on console\n"
-			 "   -d | --debug:                     enable debug output\n"
-			 "\n");
+	       "   -v | --version                    print the version\n"
+	       "   -h | --help                       print this help\n\n"
+	       "   -m | --me                         dump all me related information on console\n"
+	       "   -b | --bootguard                  dump bootguard state of the platform\n"
+	       "   -d | --debug                      enable debug output\n"
+	       "\n");
 	exit(1);
 }
 
@@ -305,21 +372,25 @@ int main(int argc, char *argv[])
 	static struct option long_options[] = {
 		{"version", 0, 0, 'v'},
 		{"help", 0, 0, 'h'},
-		{"show", 0, 0, 's'},
+		{"me", 0, 0, 'm'},
+		{"bootguard", 0, 0, 'b'},
 		{"debug", 0, 0, 'd'},
 		{0, 0, 0, 0}
 	};
 
-	while ((opt = getopt_long(argc, argv, "vh?sd",
-	                                long_options, &option_index)) != EOF) {
-	switch (opt) {
+	while ((opt = getopt_long(argc, argv, "vh?mdb",
+				  long_options, &option_index)) != EOF) {
+		switch (opt) {
 		case 'v':
 			print_version();
 			exit(0);
 			break;
-		case 's':
+		case 'm':
 			cmd_exec = 1;
 			break;
+		case 'b':
+			cmd_exec = 2;
+			break;
 		case 'd':
 			debug = 1;
 			break;
@@ -329,42 +400,52 @@ int main(int argc, char *argv[])
 			print_usage(argv[0]);
 			exit(0);
 			break;
-			}
 		}
+	}
 
 	#if defined(__FreeBSD__)
-		if (open("/dev/io", O_RDWR) < 0) {
-			perror("/dev/io");
+	if (open("/dev/io", O_RDWR) < 0) {
+		perror("/dev/io");
 	#elif defined(__NetBSD__)
 	# ifdef __i386__
-		if (i386_iopl(3)) {
-			perror("iopl");
+	if (i386_iopl(3)) {
+		perror("iopl");
 	# else
-		if (x86_64_iopl(3)) {
-			perror("iopl");
+	if (x86_64_iopl(3)) {
+		perror("iopl");
 	# endif
 	#else
-		if (iopl(3)) {
-			perror("iopl");
+	if (iopl(3)) {
+		perror("iopl");
 	#endif
-			printf("You need to be root.\n");
-			exit(1);
-		}
+		printf("You need to be root.\n");
+		exit(1);
+	}
 
 	#ifndef __DARWIN__
-		if ((fd_mem = open("/dev/mem", O_RDWR)) < 0) {
-			perror("Can not open /dev/mem");
-			exit(1);
-		}
+	if ((fd_mem = open("/dev/mem", O_RDWR)) < 0) {
+		perror("Can not open /dev/mem");
+		exit(1);
+	}
+
+	get_cpu_id(cpu_id);
+	if(strncmp(cpu_id, "GenuineIntel", CPU_ID_SIZE-1)) {
+		perror("Error CPU is not from Intel.");
+		exit(1);
+	}
 	#endif
 
 	switch(cmd_exec) {
-		case 1:
-			dump_me_info();
-			break;
-		default:
-			print_usage(argv[0]);
-			break;
+	case 1:
+		dump_me_info();
+		break;
+	case 2:
+		dump_bootguard_info();
+		break;
+	default:
+		dump_me_info();
+		dump_bootguard_info();
+		break;
 	}
 
 	return 0;
diff --git a/util/intelmetool/intelmetool.h b/util/intelmetool/intelmetool.h
index 4b9803b..bd6dcf4 100644
--- a/util/intelmetool/intelmetool.h
+++ b/util/intelmetool/intelmetool.h
@@ -22,7 +22,7 @@
 #define ME_PRESENT_CAN_DISABLE 4
 #define ME_PRESENT_CANNOT_DISABLE 5
 
-#define INTELMETOOL_VERSION "1.0"
+#define INTELMETOOL_VERSION "1.1"
 
 #if defined(__GLIBC__)
 #include <sys/io.h>
@@ -48,7 +48,14 @@
 #define CWHT  "\x1B[37m"
 #define RESET "\033[0m"
 
+#define CPU_ID_SIZE 13
+#define FD2 0x3428
+#define ME_COMMAND_DELAY 10000
+#define ME_MESSAGE_LEN 256
+#define INTEL_PLATFORM_VENDOR_ID 0x8086
+
 extern int debug;
+extern void print_cap(const char *name, int state);
 
 // Definitely has ME and can be disabled
 #define PCI_DEVICE_ID_INTEL_ICH8ME		0x2811
diff --git a/util/intelmetool/me.c b/util/intelmetool/me.c
index da5fb71..0313132 100644
--- a/util/intelmetool/me.c
+++ b/util/intelmetool/me.c
@@ -420,12 +420,6 @@ int mkhi_get_fw_version(void)
 	return 0;
 }
 
-static inline void print_cap(const char *name, int state)
-{
-	printf("ME Capability: %-30s : %s\n",
-	       name, state ? "ON" : "OFF");
-}
-
 /* Get ME Firmware Capabilities */
 int mkhi_get_fwcaps(void)
 {
@@ -463,12 +457,10 @@ int mkhi_get_fwcaps(void)
 	print_cap("Small business technology                 ", fwcaps.cap.caps_sku.small_business);
 	print_cap("Level III manageability                   ", fwcaps.cap.caps_sku.l3manageability);
 	print_cap("IntelR Anti-Theft (AT)                    ", fwcaps.cap.caps_sku.intel_at);
-	print_cap("IntelR Capability Licensing Service (CLS) ",
-		  fwcaps.cap.caps_sku.intel_cls);
-	print_cap("IntelR Power Sharing Technology (MPC)     ",
-		  fwcaps.cap.caps_sku.intel_mpc);
+	print_cap("IntelR Capability Licensing Service (CLS) ", fwcaps.cap.caps_sku.intel_cls);
+	print_cap("IntelR Power Sharing Technology (MPC)     ", fwcaps.cap.caps_sku.intel_mpc);
 	print_cap("ICC Over Clocking                         ", fwcaps.cap.caps_sku.icc_over_clocking);
-        print_cap("Protected Audio Video Path (PAVP)         ", fwcaps.cap.caps_sku.pavp);
+	print_cap("Protected Audio Video Path (PAVP)         ", fwcaps.cap.caps_sku.pavp);
 	print_cap("IPV6                                      ", fwcaps.cap.caps_sku.ipv6);
 	print_cap("KVM Remote Control (KVM)                  ", fwcaps.cap.caps_sku.kvm);
 	print_cap("Outbreak Containment Heuristic (OCH)      ", fwcaps.cap.caps_sku.och);
diff --git a/util/intelmetool/me.h b/util/intelmetool/me.h
index 76ee245..d0f4252 100644
--- a/util/intelmetool/me.h
+++ b/util/intelmetool/me.h
@@ -20,6 +20,8 @@
 #include <inttypes.h>
 #include <pci/pci.h>
 
+#include "intelmetool.h"
+
 #define ME_RETRY                100000  /* 1 second */
 #define ME_DELAY                10      /* 10 us */
 
diff --git a/util/intelmetool/mmap.c b/util/intelmetool/mmap.c
index da36eaa..bf3c378 100644
--- a/util/intelmetool/mmap.c
+++ b/util/intelmetool/mmap.c
@@ -28,8 +28,6 @@ void *map_physical_exact(uint64_t phys_addr, uint64_t mapto, size_t len) {
 
   if (virt_addr == MAP_FAILED) {
     err = errno;
-    printf("Error mapping physical memory 0x%016" PRIx64 "[0x%zx] ERRNO=%d\n",
-            phys_addr, len, err);
     return NULL;
   }
 
@@ -44,8 +42,6 @@ void *map_physical(uint64_t phys_addr, size_t len) {
 
   if (virt_addr == MAP_FAILED) {
     err = errno;
-    printf("Error mapping physical memory 0x%016" PRIx64 "[0x%zx] ERRNO=%d\n",
-            phys_addr, len, err);
     return NULL;
   }
 
diff --git a/util/intelmetool/msr.c b/util/intelmetool/msr.c
new file mode 100644
index 0000000..0274b6a
--- /dev/null
+++ b/util/intelmetool/msr.c
@@ -0,0 +1,78 @@
+/* intelmetool
+ *
+ * Copyright (C) 2013-2016 Philipp Deppenwiese <zaolin at das-labor.org>, Alexander Couzens <lynxis at fe80.eu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "msr.h"
+
+#ifndef __DARWIN__
+static int fd_msr = 0;
+
+static uint64_t rdmsr(int addr)
+{
+	uint32_t buf[2];
+	uint64_t msr = 0;
+
+	if (lseek(fd_msr, (off_t) addr, SEEK_SET) == -1) {
+		perror("Could not lseek() to MSR");
+		close(fd_msr);
+		return -1;
+	}
+
+	if (read(fd_msr, buf, 8) == 8) {
+		msr = buf[1];
+		msr <<= 32;
+		msr |= buf[0];
+		close(fd_msr);
+		return msr;
+	}
+
+	if (errno == EIO) {
+		close(fd_msr);
+		return -2;
+	} else {
+		perror("Could not read() MSR");
+		close(fd_msr);
+		return -1;
+	}
+
+	return msr;
+}
+#endif
+
+int msr_bootguard(uint64_t *msr, int debug) {
+
+#ifndef __DARWIN__
+	fd_msr = open("/dev/cpu/0/msr", O_RDONLY);
+	if (fd_msr < 0) {
+		perror("Error while opening /dev/cpu/0/msr");
+		printf("Did you run 'modprobe msr'?\n");
+		return -1;
+	}
+
+	*msr = rdmsr(MSR_BOOTGUARD);
+#endif
+
+	if(!debug) {
+		*msr &= ~0xff;
+	}
+
+	return 0;
+}
diff --git a/util/intelmetool/msr.h b/util/intelmetool/msr.h
new file mode 100644
index 0000000..b46a8da
--- /dev/null
+++ b/util/intelmetool/msr.h
@@ -0,0 +1,43 @@
+/* intelmetool
+ *
+ * Copyright (C) 2013-2016 Philipp Deppenwiese <zaolin at das-labor.org>, Alexander Couzens <lynxis at fe80.eu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <stdio.h>
+
+#define MSR_BOOTGUARD 0x13A
+
+#define BOOTGUARD_DISABLED 0x400000000
+#define BOOTGUARD_ENABLED_VERIFIED_MODE 0x100000000
+#define BOOTGUARD_ENABLED_MEASUREMENT_MODE 0x200000000
+#define BOOTGUARD_ENABLED_COMBI_MODE 0x300000000
+#define BOOTGUARD_CAPABILITY(x) ( \
+		( (x) == BOOTGUARD_DISABLED ) || \
+		( (x) == BOOTGUARD_ENABLED_VERIFIED_MODE ) || \
+		( (x) == BOOTGUARD_ENABLED_MEASUREMENT_MODE ) || \
+		( (x) == BOOTGUARD_ENABLED_COMBI_MODE ))
+
+#ifndef __DARWIN__
+
+typedef struct {
+	unsigned int ebx;
+	unsigned int edx;
+	unsigned int ecx;
+} cpu_t;
+
+extern int msr_bootguard(uint64_t *msr, int debug);
+#endif



More information about the coreboot-gerrit mailing list