diff options
-rw-r--r-- | util/inteltool/Makefile | 3 | ||||
-rw-r--r-- | util/inteltool/inteltool.c | 3 | ||||
-rw-r--r-- | util/inteltool/inteltool.h | 6 | ||||
-rw-r--r-- | util/inteltool/pcr.c | 90 | ||||
-rw-r--r-- | util/inteltool/pcr.h | 30 |
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 |