<p>Patrick Rudolph has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/25402">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">[WIP]util/intemetool: Add P2SB interface support<br><br>Try to unhide HECI using P2SB interface.<br>Tests showed that it's not possible to toggle HECI after<br>the interface has been locked. Maybe some other bits need<br>to be toggled first.<br><br>TODO: Needs test on hardware that hides the interface.<br><br>Change-Id: I6e67238095856d9937f8f392b8113d99af4cd186<br>Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com><br>---<br>M util/intelmetool/Makefile<br>M util/intelmetool/intelmetool.c<br>A util/intelmetool/p2sb.c<br>A util/intelmetool/p2sb.h<br>4 files changed, 255 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/02/25402/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/util/intelmetool/Makefile b/util/intelmetool/Makefile</span><br><span>index b455a0e..850c46b 100644</span><br><span>--- a/util/intelmetool/Makefile</span><br><span>+++ b/util/intelmetool/Makefile</span><br><span>@@ -18,9 +18,10 @@</span><br><span> INSTALL ?= /usr/bin/install</span><br><span> PREFIX  ?= /usr/local</span><br><span> CFLAGS  ?= -O0 -g -Wall -W -Wno-unused-parameter -Wno-sign-compare -Wno-unused-function</span><br><span style="color: hsl(120, 100%, 40%);">+CFLAGS  += -I../../src/commonlib/include</span><br><span> LDFLAGS += -lpci -lz</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-OBJS = intelmetool.o me.o me_status.o mmap.o rcba.o msr.o</span><br><span style="color: hsl(120, 100%, 40%);">+OBJS = intelmetool.o me.o me_status.o mmap.o rcba.o msr.o p2sb.o</span><br><span> </span><br><span> OS_ARCH       = $(shell uname)</span><br><span> ifeq ($(OS_ARCH), Darwin)</span><br><span>diff --git a/util/intelmetool/intelmetool.c b/util/intelmetool/intelmetool.c</span><br><span>index 0e75a50..34a8012 100644</span><br><span>--- a/util/intelmetool/intelmetool.c</span><br><span>+++ b/util/intelmetool/intelmetool.c</span><br><span>@@ -28,11 +28,13 @@</span><br><span> #include "mmap.h"</span><br><span> #include "msr.h"</span><br><span> #include "rcba.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "p2sb.h"</span><br><span> </span><br><span> extern int fd_mem;</span><br><span> int debug = 0;</span><br><span> </span><br><span> static uint32_t fd2 = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+static uint32_t psfx_t0_shdw_pcien = 0;</span><br><span> static int ME_major_ver = 0;</span><br><span> static int ME_minor_ver = 0;</span><br><span> </span><br><span>@@ -176,6 +178,11 @@</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define PSF_BASE_ADDRESS        0xA00</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCR_PSFX_T0_SHDW_PCIEN  0x1C</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCR_PSFX_T0_SHDW_PCIEN_FUNDIS   (1 << 8)</span><br><span style="color: hsl(120, 100%, 40%);">+#define PID_PSF1       0xBA</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int activate_me(void)</span><br><span> {</span><br><span>  const uint32_t rcba = get_rcba_phys();</span><br><span>@@ -194,6 +201,21 @@</span><br><span>                        printf("MEI was hidden on PCI, now unlocked\n");</span><br><span>           else if (debug)</span><br><span>                      printf("MEI not hidden on PCI, checking if visible\n");</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              const uint64_t p2sb = get_p2sb_phys();</span><br><span style="color: hsl(120, 100%, 40%);">+                if (debug)</span><br><span style="color: hsl(120, 100%, 40%);">+                    printf("P2SB bar: 0x%" PRIx64 "\n", p2sb);</span><br><span style="color: hsl(120, 100%, 40%);">+                if (p2sb > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (pcr_read32(PID_PSF1, PSF_BASE_ADDRESS +</span><br><span style="color: hsl(120, 100%, 40%);">+                                  PCR_PSFX_T0_SHDW_PCIEN,</span><br><span style="color: hsl(120, 100%, 40%);">+                                       &psfx_t0_shdw_pcien))</span><br><span style="color: hsl(120, 100%, 40%);">+                              printf("Error reading PCR\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (pcr_and32(PID_PSF1, PSF_BASE_ADDRESS +</span><br><span style="color: hsl(120, 100%, 40%);">+                                  PCR_PSFX_T0_SHDW_PCIEN,</span><br><span style="color: hsl(120, 100%, 40%);">+                               ~PCR_PSFX_T0_SHDW_PCIEN_FUNDIS))</span><br><span style="color: hsl(120, 100%, 40%);">+                                printf("Error writing PCR\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span>    }</span><br><span> </span><br><span>        return 0;</span><br><span>@@ -217,6 +239,15 @@</span><br><span>                     if (debug)</span><br><span>                           printf("done\n");</span><br><span>          }</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              const uint64_t p2sb = get_p2sb_phys();</span><br><span style="color: hsl(120, 100%, 40%);">+                if (p2sb > 0 &&</span><br><span style="color: hsl(120, 100%, 40%);">+                (psfx_t0_shdw_pcien & PCR_PSFX_T0_SHDW_PCIEN_FUNDIS)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (pcr_or32(PID_PSF1, PSF_BASE_ADDRESS +</span><br><span style="color: hsl(120, 100%, 40%);">+                                  PCR_PSFX_T0_SHDW_PCIEN,</span><br><span style="color: hsl(120, 100%, 40%);">+                               PCR_PSFX_T0_SHDW_PCIEN_FUNDIS))</span><br><span style="color: hsl(120, 100%, 40%);">+                          printf("Error writing PCR\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span>    }</span><br><span> }</span><br><span> </span><br><span>diff --git a/util/intelmetool/p2sb.c b/util/intelmetool/p2sb.c</span><br><span>new file mode 100644</span><br><span>index 0000000..28ce46f</span><br><span>--- /dev/null</span><br><span>+++ b/util/intelmetool/p2sb.c</span><br><span>@@ -0,0 +1,204 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2014  Damien Zammit <damien@zamaudio.com></span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2017  Patrick Rudolph <siro@das-labor.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <inttypes.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "intelmetool.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "mmap.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "p2sb.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "assert.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "commonlib/helpers.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const int size = 0x1000000;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Returns the physical P2SB base address or zero on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+u64 get_p2sb_phys(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct pci_access *pacc;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct pci_dev *sb;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint64_t p2sb_phys = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     pacc = pci_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+   pacc->method = PCI_ACCESS_I386_TYPE1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    pci_init(pacc);</span><br><span style="color: hsl(120, 100%, 40%);">+       pci_scan_bus(pacc);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sb = pci_get_dev(pacc, 0, 0, 0x1f, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!sb) {</span><br><span style="color: hsl(120, 100%, 40%);">+            printf("Uh oh, southbridge not on BDF(0:31:1), please report "</span><br><span style="color: hsl(120, 100%, 40%);">+                     "this error, exiting.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           pci_cleanup(pacc);</span><br><span style="color: hsl(120, 100%, 40%);">+            return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     pci_fill_info(sb, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_SIZES |</span><br><span style="color: hsl(120, 100%, 40%);">+                    PCI_FILL_CLASS);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  const u8 reg8 = pci_read_byte(sb, 0xe1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (pci_read_byte(sb, 0xe2) & 2) {</span><br><span style="color: hsl(120, 100%, 40%);">+                static int once;</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!once)</span><br><span style="color: hsl(120, 100%, 40%);">+                    printf("Warning: Endpoint Mask Lock Bit set !\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          once = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Make device visible */</span><br><span style="color: hsl(120, 100%, 40%);">+     pci_write_byte(sb, 0xe1, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* someone home ? */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (pci_read_word(sb, 0) == 0x0000 ||</span><br><span style="color: hsl(120, 100%, 40%);">+         pci_read_word(sb, 0) == 0xffff)</span><br><span style="color: hsl(120, 100%, 40%);">+               goto out;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Probe for memory bar */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (pci_read_long(sb, 0x10) & 1)</span><br><span style="color: hsl(120, 100%, 40%);">+          goto out;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Get Sideband Register Access address */</span><br><span style="color: hsl(120, 100%, 40%);">+    if ((pci_read_long(sb, 0x10) & 0x6) == 0x0)</span><br><span style="color: hsl(120, 100%, 40%);">+               p2sb_phys = pci_read_long(sb, 0x10) & 0xfffffff8UL;</span><br><span style="color: hsl(120, 100%, 40%);">+       else if ((pci_read_long(sb, 0x10) & 0x6) == 0x4)</span><br><span style="color: hsl(120, 100%, 40%);">+          p2sb_phys = (pci_read_long(sb, 0x10) & 0xfffffff8UL) |</span><br><span style="color: hsl(120, 100%, 40%);">+            (((unsigned long long)pci_read_long(sb, 0x14)) << 32);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+out:</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Make device invisible */</span><br><span style="color: hsl(120, 100%, 40%);">+   pci_write_byte(sb, 0xe1, reg8 | 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pci_free_dev(sb);</span><br><span style="color: hsl(120, 100%, 40%);">+     pci_cleanup(pacc);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return p2sb_phys;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Writes 'val' to P2SB register at address 'addr'.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns 1 on error and 0 on success.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static int write_p2sb32(uint32_t addr, uint32_t val)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        volatile uint8_t *p2sb;</span><br><span style="color: hsl(120, 100%, 40%);">+       const uint64_t p2sb_phys = get_p2sb_phys();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!p2sb_phys) {</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("Could not get P2SB address\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   p2sb = map_physical((off_t)p2sb_phys, size);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (p2sb == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printf("Could not map P2SB\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     *(uint32_t *)(p2sb + addr) = val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   munmap((void *)p2sb, size);</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Reads P2SB register at address 'addr' and stores it in 'val'.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns 1 on error and 0 on success.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static int read_p2sb32(uint32_t addr, uint32_t *val)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   volatile uint8_t *p2sb;</span><br><span style="color: hsl(120, 100%, 40%);">+       const uint64_t p2sb_phys = get_p2sb_phys();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!p2sb_phys) {</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("Could not get P2SB address\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   p2sb = map_physical((off_t)p2sb_phys, size);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (p2sb == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printf("Could not map P2SB\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   *val = *(uint32_t *)(p2sb + addr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  munmap((void *)p2sb, size);</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Port Id lives in bits 23:16 and register offset lives in 15:0 of address. */</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCR_PORTID_SHIFT       16</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCR_OFFSET_SHIFT    0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uint32_t __pcr_reg_address(uint8_t pid, uint16_t offset)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       return (pid << PCR_PORTID_SHIFT) | (offset << PCR_OFFSET_SHIFT);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int pcr_read32(uint8_t pid, uint16_t offset, uint32_t *val)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Ensure the PCR offset is corretcly aligned. */</span><br><span style="color: hsl(120, 100%, 40%);">+     assert(IS_ALIGNED(offset, sizeof(uint32_t)));</span><br><span style="color: hsl(120, 100%, 40%);">+ return read_p2sb32(__pcr_reg_address(pid, offset), val);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * After every write one needs to perform a read an innocuous register to</span><br><span style="color: hsl(120, 100%, 40%);">+ * ensure the writes are completed for certain ports. This is done for</span><br><span style="color: hsl(120, 100%, 40%);">+ * all ports so that the callers don't need the per-port knowledge for</span><br><span style="color: hsl(120, 100%, 40%);">+ * each transaction.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline int write_completion(uint8_t pid, uint16_t offset)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t reg32;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t a = __pcr_reg_address(pid, ALIGN_DOWN(offset, sizeof(uint32_t)));</span><br><span style="color: hsl(120, 100%, 40%);">+    return read_p2sb32(a, &reg32);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int pcr_write32(uint8_t pid, uint16_t offset, uint32_t indata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Ensure the PCR offset is corretcly aligned. */</span><br><span style="color: hsl(120, 100%, 40%);">+     assert(IS_ALIGNED(offset, sizeof(indata)));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (write_p2sb32(__pcr_reg_address(pid, offset), indata))</span><br><span style="color: hsl(120, 100%, 40%);">+             return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Ensure the writes complete. */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (write_completion(pid, offset))</span><br><span style="color: hsl(120, 100%, 40%);">+            return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int pcr_or32(uint8_t pid, uint16_t offset, uint32_t ordata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t data32;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (pcr_read32(pid, offset, &data32))</span><br><span style="color: hsl(120, 100%, 40%);">+             return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     data32 |= ordata;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (pcr_write32(pid, offset, data32))</span><br><span style="color: hsl(120, 100%, 40%);">+         return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int pcr_and32(uint8_t pid, uint16_t offset, uint32_t anddata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      uint32_t data32;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (pcr_read32(pid, offset, &data32))</span><br><span style="color: hsl(120, 100%, 40%);">+             return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     data32 &= anddata;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (pcr_write32(pid, offset, data32))</span><br><span style="color: hsl(120, 100%, 40%);">+         return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/util/intelmetool/p2sb.h b/util/intelmetool/p2sb.h</span><br><span>new file mode 100644</span><br><span>index 0000000..f5c8515</span><br><span>--- /dev/null</span><br><span>+++ b/util/intelmetool/p2sb.h</span><br><span>@@ -0,0 +1,18 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2017  Patrick Rudolph <siro@das-labor.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int pcr_read32(uint8_t pid, uint16_t offset, uint32_t *val);</span><br><span style="color: hsl(120, 100%, 40%);">+int pcr_write32(uint8_t pid, uint16_t offset, uint32_t indata);</span><br><span style="color: hsl(120, 100%, 40%);">+int pcr_or32(uint8_t pid, uint16_t offset, uint32_t ordata);</span><br><span style="color: hsl(120, 100%, 40%);">+int pcr_and32(uint8_t pid, uint16_t offset, uint32_t anddata);</span><br><span style="color: hsl(120, 100%, 40%);">+u64 get_p2sb_phys(void);</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/25402">change 25402</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/25402"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I6e67238095856d9937f8f392b8113d99af4cd186 </div>
<div style="display:none"> Gerrit-Change-Number: 25402 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <patrick.rudolph@9elements.com> </div>