summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/arch/ppc.H1
-rw-r--r--src/usr/runtime/common/hsvc_attribute_structs.H10
-rw-r--r--src/usr/runtime/fakepayload.C83
-rw-r--r--src/usr/runtime/fakepayload.H80
-rw-r--r--src/usr/runtime/hdatservice.C39
-rw-r--r--src/usr/runtime/hdatstructs.H45
-rw-r--r--src/usr/runtime/makefile46
7 files changed, 226 insertions, 78 deletions
diff --git a/src/include/arch/ppc.H b/src/include/arch/ppc.H
index e8e6701bb..ebb1f0f02 100644
--- a/src/include/arch/ppc.H
+++ b/src/include/arch/ppc.H
@@ -381,6 +381,7 @@ enum
MAGIC_BREAK = 7007, // hard-code a breakpoint
MAGIC_RANDOM = 7008, // generate random number
MAGIC_MEMORYLEAK_FUNCTION = 7009, // A memory was function called.
+ MAGIC_FAKEPAYLOAD_ENTER = 7010, // Entered the fake payload.
MAGIC_CONTINUOUS_TRACE = 7055, // extract mixed trace buffer
};
diff --git a/src/usr/runtime/common/hsvc_attribute_structs.H b/src/usr/runtime/common/hsvc_attribute_structs.H
index 4493b07d5..f291c58ef 100644
--- a/src/usr/runtime/common/hsvc_attribute_structs.H
+++ b/src/usr/runtime/common/hsvc_attribute_structs.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/usr/runtime/attribute_structs.H $ */
+/* $Source: src/usr/runtime/common/hsvc_attribute_structs.H $ */
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012 */
+/* COPYRIGHT International Business Machines Corp. 2012,2013 */
/* */
/* p1 */
/* */
@@ -20,12 +20,14 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
+#ifndef __RUNTIME_HSVC_ATTRIBUTE_STRUCTS_H
+#define __RUNTIME_HSVC_ATTRIBUTE_STRUCTS_H
+
/**
* @file attribute_structs.H
*
* @brief Shared structures with the HostServices code
*/
-
struct hsvc_proc_header_t {
uint64_t procid; //=NNNCCC
uint64_t offset; //offset to attribute header relative to start of node_data
@@ -76,3 +78,5 @@ struct hsvc_node_data_t
static const uint64_t HSVC_HUID = 0xFF000001FFFFFFFF;
static const uint64_t HSVC_PHYS_PATH = 0xFF000002FFFFFFFF;
static const uint64_t HSVC_ECMD_STRING = 0xFF000003FFFFFFFF;
+
+#endif
diff --git a/src/usr/runtime/fakepayload.C b/src/usr/runtime/fakepayload.C
new file mode 100644
index 000000000..0600bfa68
--- /dev/null
+++ b/src/usr/runtime/fakepayload.C
@@ -0,0 +1,83 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/fakepayload.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 "fakepayload.H"
+#include <string.h>
+#include <sys/mm.h>
+#include <sys/mmio.h>
+#include <util/align.H>
+#include <targeting/common/commontargeting.H>
+
+
+namespace RUNTIME
+{
+
+void FakePayload::payload()
+{
+ MAGIC_INSTRUCTION(MAGIC_FAKEPAYLOAD_ENTER); // instr 1
+
+ nap(); // instr 2
+ // Should never wake from nap, but just in case...
+ loop:
+ goto loop; // instr 3
+}
+
+const size_t FakePayload::size = 3 * sizeof(uint32_t); // 3 instructions.
+const size_t FakePayload::safeClearArea = 1 * MEGABYTE;
+
+void FakePayload::load()
+{
+ TARGETING::Target* sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(sys);
+
+ // Find payload base address and offset.
+ uint64_t base = sys->getAttr<TARGETING::ATTR_PAYLOAD_BASE>() * MEGABYTE;
+ uint64_t entry = sys->getAttr<TARGETING::ATTR_PAYLOAD_ENTRY>();
+
+ // Skip loading the payload if the address is 0.
+ if (0 == base)
+ {
+ return;
+ }
+
+ // Verify payload size.
+ assert(ALIGN_PAGE(entry + size) < safeClearArea);
+
+ // Map in the payload area.
+ void* memArea = mmio_dev_map(reinterpret_cast<void*>(base), THIRTYTWO_GB);
+
+ // Clear out anything the FSP might have left around (for security).
+ memset(memArea, '\0', safeClearArea);
+
+ // Copy over the fake payload code.
+ uint8_t* dest = reinterpret_cast<uint8_t*>(memArea) + entry;
+ memcpy(dest, *(reinterpret_cast<void**>(&payload)), size);
+
+ // Invalidate the icache since this is instructions.
+ mm_icache_invalidate(memArea, ALIGN_8(safeClearArea) / sizeof(uint64_t));
+
+ // Unmap the payload area.
+ mmio_dev_unmap(memArea);
+
+}
+
+}
diff --git a/src/usr/runtime/fakepayload.H b/src/usr/runtime/fakepayload.H
new file mode 100644
index 000000000..81cdce0a6
--- /dev/null
+++ b/src/usr/runtime/fakepayload.H
@@ -0,0 +1,80 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/fakepayload.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 __RUNTIME_FAKEPAYLOAD_H
+#define __RUNTIME_FAKEPAYLOAD_H
+
+/** @file fakepayload.H
+ * @brief Interfaces for loading a 'fake' payload when a payload is not
+ * present.
+ *
+ * The purpose of the fake payload is to be able to exercise the Hostboot
+ * shutdown path, even when there is not a real payload.
+ *
+ * This payload will simply nap all of the processors.
+ */
+#include <stdint.h>
+#include <arch/ppc.H>
+
+namespace RUNTIME
+{
+ /** @class FakePayload
+ *
+ * @brief Handles loading of the fake payload.
+ *
+ * Places the payload into the area of memory determined by the
+ * PAYLOAD_BASE / PAYLOAD_ENTRY attributes.
+ *
+ * @note This class does not perform verification that the addresses
+ * in the attributes are actually reasonable values. It is assumed
+ * that attribute verification (ex. for SecureBoot) will be done
+ * elsewhere in a central place for all payloads.
+ */
+ class FakePayload
+ {
+ public:
+ /** Load payload into memory. */
+ static void load();
+ private:
+ /** The fake payload itself. */
+ static void payload()
+ __attribute__((no_instrument_function));
+
+ /** Size of the payload (in bytes). */
+ static const size_t size;
+
+ /** @brief Size of memory to securely erase before loading
+ * the payload.
+ *
+ * For SecureBoot we cannot trust anything the FSP has left in
+ * memory. While we're loading a payload function into memory,
+ * the FSP had access to memory and could have loaded exception
+ * handlers. We need to clear out at least this much space in
+ * order to ensure that none of the interrupt handlers could be
+ * residing in memory.
+ */
+ static const size_t safeClearArea;
+ };
+}
+
+
+#endif
diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C
index a6eceed51..4ad6325f6 100644
--- a/src/usr/runtime/hdatservice.C
+++ b/src/usr/runtime/hdatservice.C
@@ -30,6 +30,7 @@
#include <vmmconst.h>
#include <util/align.H>
#include "hdatstructs.H"
+#include "fakepayload.H"
extern trace_desc_t* g_trac_runtime;
@@ -58,7 +59,7 @@ const hdatHeaderExp_t IPLPARMS_SYSTEM_HEADER = {
};
//big enough to hold all of PHYP
-const uint64_t HDAT_MEM_SIZE = 128*MEGABYTE;
+const uint64_t HDAT_MEM_SIZE = 128*MEGABYTE;
/********************
Utility Functions
@@ -138,7 +139,7 @@ errlHndl_t check_header( uint64_t i_base,
// Check the ID, Version and Name
if( (i_header->hdatStructId != i_exp.id)
- && (i_header->hdatVersion != i_exp.version)
+ && (i_header->hdatVersion != i_exp.version)
&& !memcmp(i_header->hdatStructName,i_exp.name,6) )
{
TRACFCOMP( g_trac_runtime, ERR_MRK "RUNTIME::check_header> HDAT Header data not as expected (id:version:name). Act=%.4X:%.4X:%s, Exp=%.4X:%.4X :%s", i_header->hdatStructId, i_header->hdatVersion, i_header->hdatStructName, i_exp.id, i_exp.version, i_exp.name );
@@ -311,7 +312,7 @@ errlHndl_t RUNTIME::load_host_data( void )
// get the current payload kind
TARGETING::ATTR_PAYLOAD_KIND_type payload_kind
= sys->getAttr<TARGETING::ATTR_PAYLOAD_KIND>();
-
+
// read the mfg flags
TARGETING::ATTR_MNFG_FLAGS_type mnfg_flags
= sys->getAttr<TARGETING::ATTR_MNFG_FLAGS>();
@@ -365,36 +366,12 @@ errlHndl_t RUNTIME::load_host_data( void )
hdat_size );
errhdl->collectTrace("RUNTIME",1024);
break;
- }
+ }
}
else if( TARGETING::PAYLOAD_KIND_NONE == payload_kind )
{
// Standalone Test Image with no payload
-
- // Ensure that there really is no payload being loaded
- TARGETING::ATTR_PAYLOAD_BASE_type payload_base
- = sys->getAttr<TARGETING::ATTR_PAYLOAD_BASE>();
- if( payload_base != 0 )
- {
- TRACFCOMP( g_trac_runtime, "load_host_data> Non-zero PAYLOAD_BASE (0x%X) for PAYLOAD_KIND==NONE", payload_base );
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA
- * @reasoncode RUNTIME::RC_WRONG_PAYLOAD_ATTRS
- * @userdata1 PAYLOAD_BASE
- * @userdata2 PAYLOAD_KIND
- * @devdesc Nonzero PAYLOAD_BASE for standalone
- * PAYLOAD_KIND
- */
- errhdl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA,
- RUNTIME::RC_WRONG_PAYLOAD_ATTRS,
- payload_base,
- payload_kind );
- errhdl->collectTrace("RUNTIME",1024);
- break;
- }
+ FakePayload::load();
// Map in some arbitrary memory for the HostServices code to use
TRACFCOMP( g_trac_runtime, "load_host_data> STANDALONE: Mapping in 0x%X-0x%X (%d MB)", HSVC_TEST_MEMORY_ADDR, HSVC_TEST_MEMORY_ADDR+HSVC_TEST_MEMORY_SIZE, HSVC_TEST_MEMORY_SIZE );
@@ -450,8 +427,8 @@ errlHndl_t RUNTIME::load_host_data( void )
DUMP_TEST_TABLE_SIZE);
errhdl->collectTrace("RUNTIME",1024);
break;
- }
-
+ }
+
}
else
{
diff --git a/src/usr/runtime/hdatstructs.H b/src/usr/runtime/hdatstructs.H
index d96a51883..e1e9be925 100644
--- a/src/usr/runtime/hdatstructs.H
+++ b/src/usr/runtime/hdatstructs.H
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012 */
+/* COPYRIGHT International Business Machines Corp. 2012,2013 */
/* */
/* p1 */
/* */
@@ -20,13 +20,16 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
+#ifndef __RUNTIME_HDATSTRUCTS_H
+#define __RUNTIME_HDATSTRUCTS_H
+
#include <stdint.h>
#include <vmmconst.h>
#include <string.h>
// Copied from FipS:src/hdat/fsp/hdatnaca.H
// offset in mainstore where NACA starts
-const uint64_t HDAT_NACA_OFFSET = 0x00004000;
+const uint64_t HDAT_NACA_OFFSET = 0x00004000;
/* NOTE: Most of these structures were copied and adapted from the HDAT
@@ -39,16 +42,16 @@ const uint64_t HDAT_NACA_OFFSET = 0x00004000;
* The NACA is a data structure used primarily by the host operating
* system. The NACA is prebuilt as part of the primary host LID. FipS
* uses several fields in the NACA to determine where the LID table
- * and the Service Processor Interace Root Array reside.
+ * and the Service Processor Interace Root Array reside.
* Fields which are not used by FipS are just defined as reserved so
* that we don't have to chase uninteresting changes the host OS may
* make to things FipS does not care about.
*/
struct hdatNaca_t
{
- uint8_t reserved1[48]; // 0x0000 Reserved space
- uint64_t spira; // 0x0030 SPIRA offset
- uint8_t reserved2[104]; // 0x0038 Reserved space
+ uint8_t reserved1[48]; // 0x0000 Reserved space
+ uint64_t spira; // 0x0030 SPIRA offset
+ uint8_t reserved2[104]; // 0x0038 Reserved space
uint32_t spiraSize; // 0x00A0 Actual SPIRA size in bytes
uint8_t nacaReserved4[28]; // 0x00A4 reserved space
uint64_t nacaHypLoadMap; // 0x00C0 Hyp resident module load map
@@ -93,15 +96,15 @@ enum hdatSpiraDataAreas
HDAT_MDT = 14, // memory description tree
HDAT_IO_HUB = 15, // I/O hub FRU array
HDAT_CPU_CTRL = 16, // CPU controls
- HDAT_MS_DUMP_SRC_TBL = 17, // mainstore dump source table
- HDAT_MS_DUMP_DST_TBL = 18, // mainstore dump destination table
+ HDAT_MS_DUMP_SRC_TBL = 17, // mainstore dump source table
+ HDAT_MS_DUMP_DST_TBL = 18, // mainstore dump destination table
HDAT_MS_DUMP_RSLT_TBL = 19, // mainstore dump results table
HDAT_SPIRA_DA_GA1LAST = 20, // End of list for 1st eclipz release
- HDAT_HEAP = 20, // Phyp allocated storage location
- HDAT_PCIA = 21, // PCIA (Core information area)
- HDAT_PCRD = 22, // PCRD (Chip related data area)
+ HDAT_HEAP = 20, // Phyp allocated storage location
+ HDAT_PCIA = 21, // PCIA (Core information area)
+ HDAT_PCRD = 22, // PCRD (Chip related data area)
HSVC_DATA = 23, // Host Services Data
- HDAT_SPIRA_DA_LAST = 24
+ HDAT_SPIRA_DA_LAST = 24
};
@@ -123,11 +126,11 @@ struct hdat5Tuple_t
// Copied from FipS:src/hdat/fsp/hdat.H
/** @brief Type definition for the common hypervisor Data Interface
- * Format (HDIF) header.
+ * Format (HDIF) header.
*/
struct hdatHDIF_t
{
- uint16_t hdatStructId; // 0x0000 Structure format ID
+ uint16_t hdatStructId; // 0x0000 Structure format ID
char hdatStructName[6]; // 0x0002 Structure eye catcher
uint16_t hdatInstance; // 0x0008 Instance number
uint16_t hdatVersion; // 0x000A Structure version
@@ -145,32 +148,32 @@ struct hdatHDIF_t
*/
struct hdatHDIFChildHdr_t
{
- uint32_t hdatOffset; // 0x0000 Offset from top of structure
+ uint32_t hdatOffset; // 0x0000 Offset from top of structure
uint32_t hdatSize; // 0x0004 Child data structure size in bytes
uint32_t hdatCnt; // 0x0008 Count of child data structures
} __attribute__ ((packed));
// Copied from FipS:src/hdat/fsp/hdat.H
-/** @brief Type definition for the "pointer" header to the internal data.
+/** @brief Type definition for the "pointer" header to the internal data.
*/
struct hdatHDIFDataHdr_t
{
- uint32_t hdatOffset; // 0x0000 Offset from top of structure
+ uint32_t hdatOffset; // 0x0000 Offset from top of structure
uint32_t hdatSize; // 0x0004 Data structure size in bytes
} __attribute__ ((packed));
// Copied from FipS:src/hdat/fsp/hdat.H
-/** @brief Type definition for the data array header. Used when internal
- * data is an array.
+/** @brief Type definition for the data array header. Used when internal
+ * data is an array.
*/
struct hdatHDIFDataArray_t
{
uint32_t hdatOffset; // 0x0000 Offset to array from this structure
uint32_t hdatArrayCnt; // 0x0004 Number of array entries
uint32_t hdatAllocSize; // 0x0008 Size of allocated space for array entry
- uint32_t hdatActSize; // 0x000C Actual size of an array entry
+ uint32_t hdatActSize; // 0x000C Actual size of an array entry
} __attribute__ ((packed));
@@ -241,4 +244,4 @@ struct hdatHeaderExp_t
return retval;
};
};
-
+#endif
diff --git a/src/usr/runtime/makefile b/src/usr/runtime/makefile
index e5ef5bf81..8482289a0 100644
--- a/src/usr/runtime/makefile
+++ b/src/usr/runtime/makefile
@@ -1,25 +1,25 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/usr/runtime/makefile $
-#
-# IBM CONFIDENTIAL
-#
-# COPYRIGHT International Business Machines Corp. 2012
-#
-# 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
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/runtime/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2012,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
#
# The runtime module provides code to handle manipulating data
@@ -30,7 +30,7 @@
ROOTPATH = ../../..
MODULE = runtime
-OBJS = populate_attributes.o hdatservice.o
+OBJS = populate_attributes.o hdatservice.o fakepayload.o
SUBDIRS = test.d
OpenPOWER on IntegriCloud