summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/inteltool/Makefile3
-rw-r--r--util/inteltool/inteltool.c3
-rw-r--r--util/inteltool/inteltool.h6
-rw-r--r--util/inteltool/pcr.c90
-rw-r--r--util/inteltool/pcr.h30
5 files changed, 131 insertions, 1 deletions
diff --git a/util/inteltool/Makefile b/util/inteltool/Makefile
index 179bea9f85..d0f04899f0 100644
--- a/util/inteltool/Makefile
+++ b/util/inteltool/Makefile
@@ -27,7 +27,8 @@ LDFLAGS += -lpci -lz
CPPFLAGS += -I$(top)/src/commonlib/include
-OBJS = inteltool.o cpu.o gpio.o rootcmplx.o powermgt.o memory.o pcie.o amb.o ivy_memory.o spi.o gfx.o ahci.o
+OBJS = inteltool.o pcr.o cpu.o gpio.o rootcmplx.o powermgt.o \
+ memory.o pcie.o amb.o ivy_memory.o spi.o gfx.o ahci.o \
OS_ARCH = $(shell uname)
ifeq ($(OS_ARCH), Darwin)
diff --git a/util/inteltool/inteltool.c b/util/inteltool/inteltool.c
index 688e74342f..7cd4363129 100644
--- a/util/inteltool/inteltool.c
+++ b/util/inteltool/inteltool.c
@@ -24,6 +24,7 @@
#include <sys/mman.h>
#include <unistd.h>
#include "inteltool.h"
+#include "pcr.h"
#ifdef __NetBSD__
#include <machine/sysarch.h>
@@ -511,6 +512,7 @@ int main(int argc, char *argv[])
#endif
pacc = pci_alloc();
+ pacc->method = PCI_ACCESS_I386_TYPE1;
pci_init(pacc);
pci_scan_bus(pacc);
@@ -681,6 +683,7 @@ int main(int argc, char *argv[])
print_sgx();
/* Clean up */
+ pcr_cleanup();
if (ahci)
pci_free_dev(ahci);
if (gfx)
diff --git a/util/inteltool/inteltool.h b/util/inteltool/inteltool.h
index 512bdbaee3..22eda6ead8 100644
--- a/util/inteltool/inteltool.h
+++ b/util/inteltool/inteltool.h
@@ -14,6 +14,9 @@
* GNU General Public License for more details.
*/
+#ifndef INTELTOOL_H
+#define INTELTOOL_H 1
+
#include <commonlib/helpers.h>
#include <stdint.h>
@@ -139,6 +142,7 @@ static inline uint32_t inl(unsigned port)
#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_PREM 0x9cc3
#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP 0x9cc5
#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_SATA 0xa102
+#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_P2SB 0xa120
#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_PRE 0xa141
#define PCI_DEVICE_ID_INTEL_H110 0xa143
#define PCI_DEVICE_ID_INTEL_H170 0xa144
@@ -307,3 +311,5 @@ int print_gfx(struct pci_dev *gfx);
int print_ahci(struct pci_dev *ahci);
int print_sgx(void);
void ivybridge_dump_timings(const char *dump_spd_file);
+
+#endif
diff --git a/util/inteltool/pcr.c b/util/inteltool/pcr.c
new file mode 100644
index 0000000000..0310e2eba1
--- /dev/null
+++ b/util/inteltool/pcr.c
@@ -0,0 +1,90 @@
+/*
+ * inteltool - dump all registers on an Intel CPU + chipset based system.
+ *
+ * Copyright (C) 2017 secunet Security Networks AG
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <assert.h>
+#include "pcr.h"
+
+const uint8_t *sbbar = NULL;
+
+uint32_t read_pcr32(const uint8_t port, const uint16_t offset)
+{
+ assert(sbbar);
+ return *(const uint32_t *)(sbbar + (port << 16) + offset);
+}
+
+void pcr_init(struct pci_dev *const sb)
+{
+ bool error_exit = false;
+ bool p2sb_revealed = false;
+
+ if (sbbar)
+ return;
+
+ struct pci_dev *const p2sb = pci_get_dev(sb->access, 0, 0, 0x1f, 1);
+
+ if (!p2sb) {
+ perror("Can't allocate device node for P2SB.");
+ exit(1);
+ }
+
+ /* do not fill bases here, libpci refuses to refill later */
+ pci_fill_info(p2sb, PCI_FILL_IDENT);
+ if (p2sb->vendor_id == 0xffff && p2sb->device_id == 0xffff) {
+ printf("Trying to reveal Primary to Sideband Bridge "
+ "(P2SB),\nlet's hope the OS doesn't mind... ");
+ /* Do not use pci_write_long(). Surrounding
+ bytes 0xe0 must be maintained. */
+ pci_write_byte(p2sb, 0xe0 + 1, 0);
+
+ pci_fill_info(p2sb, PCI_FILL_IDENT | PCI_FILL_RESCAN);
+ if (p2sb->vendor_id != 0xffff ||
+ p2sb->device_id != 0xffff) {
+ printf("done.\n");
+ p2sb_revealed = true;
+ } else {
+ printf("failed.\n");
+ exit(1);
+ }
+ }
+ pci_fill_info(p2sb, PCI_FILL_BASES | PCI_FILL_CLASS);
+
+ const pciaddr_t sbbar_phys = p2sb->base_addr[0] & ~0xfULL;
+ printf("SBREG_BAR = 0x%08"PRIx64" (MEM)\n\n", (uint64_t)sbbar_phys);
+ sbbar = map_physical(sbbar_phys, SBBAR_SIZE);
+ if (sbbar == NULL) {
+ perror("Error mapping SBREG_BAR");
+ error_exit = true;
+ }
+
+ if (p2sb_revealed) {
+ printf("Hiding Primary to Sideband Bridge (P2SB).\n");
+ pci_write_byte(p2sb, 0xe0 + 1, 1);
+ }
+ pci_free_dev(p2sb);
+
+ if (error_exit)
+ exit(1);
+}
+
+void pcr_cleanup(void)
+{
+ if (sbbar)
+ unmap_physical((void *)sbbar, SBBAR_SIZE);
+}
diff --git a/util/inteltool/pcr.h b/util/inteltool/pcr.h
new file mode 100644
index 0000000000..601cfb6874
--- /dev/null
+++ b/util/inteltool/pcr.h
@@ -0,0 +1,30 @@
+/*
+ * inteltool - dump all registers on an Intel CPU + chipset based system.
+ *
+ * Copyright (C) 2017 secunet Security Networks AG
+ *
+ * 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; version 2 of the License.
+ *
+ * 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.
+ */
+
+#ifndef INTELTOOL_PCR_H
+#define INTELTOOL_PCR_H 1
+
+#include <stdint.h>
+#include "inteltool.h"
+
+#define SBBAR_SIZE (16 * MiB)
+#define PCR_PORT_SIZE (64 * KiB)
+
+uint32_t read_pcr32(uint8_t port, uint16_t offset);
+
+void pcr_init(struct pci_dev *sb);
+void pcr_cleanup(void);
+
+#endif