summaryrefslogtreecommitdiffstats
path: root/src/usr/secureboot/base
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2013-03-26 11:23:47 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-06-14 09:09:09 -0500
commite89e72d2f8a2efe86acad95ed0769aa7a8fe64ae (patch)
tree5541b72a698f58757ab2fe36b1a264fff6bcb3a2 /src/usr/secureboot/base
parent92255af10842c672550a586d342c67ac1c7e11ca (diff)
downloadtalos-hostboot-e89e72d2f8a2efe86acad95ed0769aa7a8fe64ae.tar.gz
talos-hostboot-e89e72d2f8a2efe86acad95ed0769aa7a8fe64ae.zip
Secureboot memory layout support.
* Start kernel in 1/4 cache mode per Secureboot. * Copy Secureboot header for base image for later use. * Blind-purge bottom half of cache. * Add bottom of cache into memory maps for 1/2 cache mode. RTC: 64762 Change-Id: I1b45f30a2d45c9709d4fd486cfe0ca2ce86b051c Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/3773 Reviewed-by: Michael Baiocchi <baiocchi@us.ibm.com> Tested-by: Jenkins Server Reviewed-by: ADAM R. MUHLE <armuhle@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/secureboot/base')
-rw-r--r--src/usr/secureboot/base/header.C57
-rw-r--r--src/usr/secureboot/base/makefile30
-rw-r--r--src/usr/secureboot/base/purge.C140
-rw-r--r--src/usr/secureboot/base/purge.H35
-rw-r--r--src/usr/secureboot/base/service.C68
-rw-r--r--src/usr/secureboot/base/settings.C52
6 files changed, 382 insertions, 0 deletions
diff --git a/src/usr/secureboot/base/header.C b/src/usr/secureboot/base/header.C
new file mode 100644
index 000000000..00f808e1b
--- /dev/null
+++ b/src/usr/secureboot/base/header.C
@@ -0,0 +1,57 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/base/header.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "header.H"
+#include <sys/mm.h>
+#include <sys/mmio.h>
+#include <kernel/console.H>
+
+namespace SECUREBOOT
+{
+ void Header::loadBaseHeader()
+ {
+ // Calculate original address of the secureboot header.
+ // Zero is purposefully not mapped into the VMM tables, so we
+ // can't use that for the virtual-to-real translation. Since
+ // this object is in the base image, EA = HRMOR | PA, so we can
+ // use PA - EA to find the HRMOR.
+ uint64_t addr = mm_virt_to_phys(this) -
+ reinterpret_cast<uint64_t>(this);
+ addr -= PAGESIZE;
+
+ // Map in the header.
+ void* origHeader = mm_block_map(reinterpret_cast<void*>(addr),
+ PAGESIZE);
+
+ // Copy header to a save area.
+ // In the future we might want to just extract pieces of the
+ // header. The header is important when we start updating
+ // the TPM PCRs.
+ iv_data = malloc(PAGESIZE);
+ memcpy(iv_data, origHeader, PAGESIZE);
+
+ // Unmap the header.
+ mm_block_unmap(origHeader);
+
+ return;
+ }
+}
diff --git a/src/usr/secureboot/base/makefile b/src/usr/secureboot/base/makefile
new file mode 100644
index 000000000..8a63e1537
--- /dev/null
+++ b/src/usr/secureboot/base/makefile
@@ -0,0 +1,30 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/secureboot/base/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2013
+#
+# p1
+#
+# Object Code Only (OCO) source materials
+# Licensed Internal Code Source Materials
+# IBM HostBoot Licensed Internal Code
+#
+# The source code for this program is not published or otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+ROOTPATH = ../../../..
+MODULE = secureboot_base
+SUBDIRS =
+
+OBJS = service.o settings.o header.o purge.o
+
+CFLAGS += -iquote ../
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/secureboot/base/purge.C b/src/usr/secureboot/base/purge.C
new file mode 100644
index 000000000..af21a7b02
--- /dev/null
+++ b/src/usr/secureboot/base/purge.C
@@ -0,0 +1,140 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/base/purge.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <stdint.h>
+#include <sys/task.h>
+#include <sys/time.h>
+#include <devicefw/userif.H>
+#include <secureboot/secure_reasoncodes.H>
+
+#include "purge.H"
+
+namespace SECUREBOOT
+{
+ errlHndl_t issueBlindPurge()
+ {
+ static const uint64_t PURGE_REG = 0x1001080e;
+
+ // Bits : Value
+ // 0 : 0b1 = Initiate Purge
+ // 1:4 : 0b0100 = Full Blind Purge
+ // 13:28 : 0x1000 = CGC is (512k / 128 byte line size)
+ // CGC means "Congruence Class", ie. cache row.
+ static const uint64_t PURGE_VALUE = 0xa000800000000000;
+
+ // Bit 0 - Purge Pending.
+ static const uint64_t PURGE_PENDING = 0x8000000000000000;
+
+ static const size_t RETRY_COUNT = 100;
+ static const size_t RETRY_WAIT_NS = ONE_CTX_SWITCH_NS;
+
+ errlHndl_t l_errl = NULL;
+ do
+ {
+ size_t coreId = (task_getcpuid() / 8) & 0xF;
+ uint64_t regAddr = PURGE_REG + 0x01000000 * coreId;
+
+ uint64_t data = 0;
+ size_t size = sizeof(data);
+
+ // Read purge register to ensure no operation is pending.
+ l_errl =
+ deviceRead(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL,
+ &data, size,
+ DEVICE_SCOM_ADDRESS(regAddr));
+ if (l_errl)
+ {
+ break;
+ }
+
+ if (data & PURGE_PENDING)
+ {
+ /*@
+ * @errortype
+ * @moduleid SECUREBOOT::MOD_SECURE_BLINDPURGE
+ * @reasoncode SECUREBOOT::RC_PURGEOP_PENDING
+ * @userdata1 SCOM value.
+ * @userdata2 CPU ID (PIR) encountering failure.
+ * @devdesc Attemped to purge cache while purge operation
+ * was pending.
+ */
+ l_errl =
+ new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_SECURE_BLINDPURGE,
+ RC_PURGEOP_PENDING,
+ data, task_getcpuid());
+ break;
+ }
+
+ // Initiate purge operation
+ data = PURGE_VALUE;
+ l_errl =
+ deviceWrite(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL,
+ &data, size,
+ DEVICE_SCOM_ADDRESS(regAddr));
+ if (l_errl)
+ {
+ break;
+ }
+
+ // Wait for purge to complete.
+ for(size_t i = 0; i < RETRY_COUNT; i++)
+ {
+ l_errl =
+ deviceRead(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL,
+ &data, size,
+ DEVICE_SCOM_ADDRESS(regAddr));
+
+ if ((l_errl) || !(data & PURGE_PENDING))
+ {
+ break;
+ }
+
+ nanosleep(0, RETRY_WAIT_NS);
+ }
+ if (l_errl)
+ {
+ break;
+ }
+ if (data & PURGE_PENDING) // Ensure op did complete.
+ {
+ /*@
+ * @errortype
+ * @moduleid SECUREBOOT::MOD_SECURE_BLINDPURGE
+ * @reasoncode SECUREBOOT::RC_PURGEOP_FAIL_COMPLETE
+ * @userdata1 SCOM value.
+ * @devdesc Purge operation never completed.
+ */
+ l_errl =
+ new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_SECURE_BLINDPURGE,
+ RC_PURGEOP_FAIL_COMPLETE,
+ data);
+ break;
+ }
+
+ } while(0);
+
+ return l_errl;
+ }
+
+}
diff --git a/src/usr/secureboot/base/purge.H b/src/usr/secureboot/base/purge.H
new file mode 100644
index 000000000..f10edf0aa
--- /dev/null
+++ b/src/usr/secureboot/base/purge.H
@@ -0,0 +1,35 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/base/purge.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SECUREBOOT_PURGE_H
+#define __SECUREBOOT_PURGE_H
+
+#include <errl/errlentry.H>
+
+namespace SECUREBOOT
+{
+ /** @brief Issues the SCOMs to the master EX's L3 to perform a blind purge.
+ */
+ errlHndl_t issueBlindPurge();
+}
+
+#endif
diff --git a/src/usr/secureboot/base/service.C b/src/usr/secureboot/base/service.C
new file mode 100644
index 000000000..bb18bef9f
--- /dev/null
+++ b/src/usr/secureboot/base/service.C
@@ -0,0 +1,68 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/base/service.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <secureboot/service.H>
+#include <stdint.h>
+#include <sys/mm.h>
+#include <util/singleton.H>
+#include <secureboot/secure_reasoncodes.H>
+
+#include "settings.H"
+#include "header.H"
+#include "purge.H"
+
+namespace SECUREBOOT
+{
+ void* initializeBase(void* unused)
+ {
+ errlHndl_t l_errl = NULL;
+
+ do
+ {
+ // Load original secureboot header.
+ if (enabled())
+ {
+ Singleton<Header>::instance().loadBaseHeader();
+ }
+
+ // Blind-purge lower portion of cache.
+ l_errl = issueBlindPurge();
+ if (l_errl)
+ {
+ break;
+ }
+
+ // Extend memory footprint into lower portion of cache.
+ // This can only fail is someone has already called to extend
+ // to post-secureboot state. Major coding bug, so just assert.
+ assert(0 == mm_extend(MM_EXTEND_POST_SECUREBOOT));
+
+ } while(0);
+
+ return l_errl;
+ }
+
+ bool enabled()
+ {
+ return Singleton<Settings>::instance().getEnabled();
+ }
+}
diff --git a/src/usr/secureboot/base/settings.C b/src/usr/secureboot/base/settings.C
new file mode 100644
index 000000000..dfacf46e7
--- /dev/null
+++ b/src/usr/secureboot/base/settings.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/base/settings.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <errl/errlentry.H>
+#include <devicefw/userif.H>
+
+#include "settings.H"
+
+namespace SECUREBOOT
+{
+ const uint64_t Settings::SECURITY_SWITCH_REGISTER = 0x00010005;
+ const uint64_t
+ Settings::SECURITY_SWITCH_TRUSTED_BOOT = 0x4000000000000000ull;
+
+ void Settings::_init()
+ {
+ errlHndl_t l_errl = NULL;
+ size_t size = sizeof(iv_regValue);
+
+ // Read / cache security switch setting from processor.
+ l_errl = deviceRead(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL,
+ &iv_regValue, size,
+ DEVICE_SCOM_ADDRESS(SECURITY_SWITCH_REGISTER));
+
+ // If this errors, we're in bad shape and shouldn't trust anything.
+ assert(NULL == l_errl);
+ }
+
+ bool Settings::getEnabled()
+ {
+ return 0 != (iv_regValue & SECURITY_SWITCH_TRUSTED_BOOT);
+ }
+}
OpenPOWER on IntegriCloud