summaryrefslogtreecommitdiffstats
path: root/src/sbefw
diff options
context:
space:
mode:
Diffstat (limited to 'src/sbefw')
-rw-r--r--src/sbefw/Makefile56
-rw-r--r--src/sbefw/assert.h49
-rw-r--r--src/sbefw/pk_app_cfg.h144
-rw-r--r--src/sbefw/plugins/sbeUserDataParser.C292
-rw-r--r--src/sbefw/pool.C65
-rw-r--r--src/sbefw/pool.H58
-rw-r--r--src/sbefw/sbeFFDC.C141
-rw-r--r--src/sbefw/sbeFFDC.H125
-rw-r--r--src/sbefw/sbeFFDCType.H100
-rw-r--r--src/sbefw/sbeFifoMsgUtils.C375
-rw-r--r--src/sbefw/sbeFifoMsgUtils.H192
-rw-r--r--src/sbefw/sbeHostMsg.H132
-rw-r--r--src/sbefw/sbeHostUtils.C226
-rw-r--r--src/sbefw/sbeHostUtils.H244
-rw-r--r--src/sbefw/sbeSpMsg.H634
-rw-r--r--src/sbefw/sbeXipUtils.H63
-rw-r--r--src/sbefw/sbe_host_intf.H89
-rw-r--r--src/sbefw/sbe_sp_intf.H408
-rw-r--r--src/sbefw/sbecmdcntlinst.C203
-rw-r--r--src/sbefw/sbecmdcntlinst.H45
-rw-r--r--src/sbefw/sbecmdcntrldmt.C302
-rw-r--r--src/sbefw/sbecmdcntrldmt.H59
-rw-r--r--src/sbefw/sbecmdgeneric.C118
-rw-r--r--src/sbefw/sbecmdgeneric.H46
-rw-r--r--src/sbefw/sbecmdiplcontrol.C830
-rw-r--r--src/sbefw/sbecmdiplcontrol.H117
-rw-r--r--src/sbefw/sbecmdmemaccess.C778
-rw-r--r--src/sbefw/sbecmdmemaccess.H54
-rw-r--r--src/sbefw/sbecmdparser.C483
-rw-r--r--src/sbefw/sbecmdparser.H119
-rw-r--r--src/sbefw/sbecmdprocessor.C376
-rw-r--r--src/sbefw/sbecmdreceiver.C325
-rw-r--r--src/sbefw/sbecmdregaccess.C274
-rw-r--r--src/sbefw/sbecmdregaccess.H56
-rw-r--r--src/sbefw/sbecmdringaccess.C305
-rw-r--r--src/sbefw/sbecmdringaccess.H63
-rw-r--r--src/sbefw/sbecmdscomaccess.C495
-rw-r--r--src/sbefw/sbecmdscomaccess.H93
-rw-r--r--src/sbefw/sbecmdsram.C337
-rw-r--r--src/sbefw/sbecmdsram.H64
-rw-r--r--src/sbefw/sbeerrorcodes.H49
-rw-r--r--src/sbefw/sbeevents.H96
-rw-r--r--src/sbefw/sbeexeintf.H256
-rw-r--r--src/sbefw/sbefifo.H227
-rw-r--r--src/sbefw/sbefwfiles.mk48
-rw-r--r--src/sbefw/sbeirq.C195
-rw-r--r--src/sbefw/sbeirq.H109
-rw-r--r--src/sbefw/sbemain.C352
-rw-r--r--src/sbefw/sberegaccess.C331
-rw-r--r--src/sbefw/sberegaccess.H266
-rw-r--r--src/sbefw/sbescom.C198
-rw-r--r--src/sbefw/sbescom.H38
-rw-r--r--src/sbefw/sbestates.H67
-rw-r--r--src/sbefw/sbetrace.H75
-rw-r--r--src/sbefw/sbeutil.H81
-rw-r--r--src/sbefw/vector397
56 files changed, 11720 insertions, 0 deletions
diff --git a/src/sbefw/Makefile b/src/sbefw/Makefile
new file mode 100644
index 00000000..f25f44f5
--- /dev/null
+++ b/src/sbefw/Makefile
@@ -0,0 +1,56 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/sbefw/Makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+#export P2P_ENABLE = 1
+
+export SUB_OBJDIR = /sbefw
+
+include img_defs.mk
+include sbefwfiles.mk
+
+OBJS := $(addprefix $(OBJDIR)/, $(SBEFW_OBJECTS))
+
+libsbefw.a: $(OBJS)
+ $(AR) crs $(OBJDIR)/libsbefw.a $(OBJDIR)/*.o
+
+.PHONY: clean sbefw
+sbefw: $(OBJS)
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+
+#clean the kernel directory first, then the application level clean
+clean:
+ rm -fr $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
+
+
+
+
+
diff --git a/src/sbefw/assert.h b/src/sbefw/assert.h
new file mode 100644
index 00000000..4a5be085
--- /dev/null
+++ b/src/sbefw/assert.h
@@ -0,0 +1,49 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/assert.h $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file assert.h
+ *
+ * @brief This file contains the assert macro for SBE
+ */
+#ifndef SBE_ASSERT_H
+#define SBE_ASSERT_H
+#include "sbetrace.H"
+#include "sbeutil.H"
+
+//@TODO via RTC 129166
+//inject exception to halt SBE. Also see if we can use some
+//PK kernel API.
+#ifndef NDEBUG
+#define assert(expr) \
+ if( !(expr )) \
+ { \
+ SBE_ERROR("assertion failed: "#expr); \
+ PK_PANIC(SBE::PANIC_ASSERT); \
+ } \
+
+#else
+#define assert(expr)
+#endif //NDEBUG
+
+#endif // SBE_ASSERT_H
diff --git a/src/sbefw/pk_app_cfg.h b/src/sbefw/pk_app_cfg.h
new file mode 100644
index 00000000..d2fbfceb
--- /dev/null
+++ b/src/sbefw/pk_app_cfg.h
@@ -0,0 +1,144 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/pk_app_cfg.h $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/pk_app_cfg.h
+ *
+ * @brief Application specific overrides go here.
+ *
+ */
+
+#ifndef __PK_APP_CFG_H__
+#define __PK_APP_CFG_H__
+
+#include "sbeirq.H"
+
+/*
+ * @brief Static configuration data for external interrupts:
+ * IRQ#, TYPE, POLARITY, ENABLE
+ *
+ */
+#define APPCFG_EXT_IRQS_CONFIG \
+ SBE_IRQ_START0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_START1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_INTR0 STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_INTR1 STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_DRTM_REQ STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_SBEFIFO_RESET STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_SBEFIFO_DATA STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_HOST_PSU_INTR STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+
+
+/*
+ * @brief This 64 bit mask specifies which of the interrupts are not to be used.
+ *
+ */
+#define APPCFG_IRQ_INVALID_MASK \
+(\
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_8) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_9) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_10) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_11) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_12) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_13) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_14) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_15) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_16) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_17) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_18) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_19) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_20) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_21) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_22) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_23) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_24) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_25) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_26) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_27) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_28) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_29) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_30) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_31) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_32) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_33) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_34) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_35) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_36) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_37) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_38) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_39) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_40) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_41) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_42) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_43) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_44) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_45) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_46) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_47) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_48) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_49) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_50) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_51) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_52) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_53) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_54) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_55) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_56) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_57) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_58) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_59) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_60) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_61) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_62) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_63))
+
+
+/*
+ * @brief Override the default behavior of the PK API error handling.
+ * Force PK to send the return code back to the application,
+ * instead of a kernel panic.
+ *
+ */
+#ifndef PK_ERROR_PANIC
+#define PK_ERROR_PANIC 0
+#endif
+
+/*
+ * @brief Override the default behavior of idle timer trace.
+ * As SBE trace buffer is small, we do not want idle timer traces.
+ *
+ */
+#define PK_TRACE_TIMER_OUTPUT 0
+
+#ifdef PPE42_MACHINE_CHECK_HANDLER
+#undef PPE42_MACHINE_CHECK_HANDLER
+#endif
+#define PPE42_MACHINE_CHECK_HANDLER SBE_MACHINE_CHECK_HANDLER
+
+// Set the trace buffer size
+#ifdef PK_TRACE_SZ
+#undef PK_TRACE_SZ
+#endif
+#define PK_TRACE_SZ 4*1024
+
+#endif /*__PK_APP_CFG_H__*/
diff --git a/src/sbefw/plugins/sbeUserDataParser.C b/src/sbefw/plugins/sbeUserDataParser.C
new file mode 100644
index 00000000..9ad2f48e
--- /dev/null
+++ b/src/sbefw/plugins/sbeUserDataParser.C
@@ -0,0 +1,292 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/plugins/sbeUserDataParser.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <sys/stat.h>
+#include <errno.h>
+
+#include <cstdlib>
+#include <cstring>
+#include <sstream>
+
+#include <utilfile.H>
+#include <utilmem.H>
+
+#include "sbeFFDCType.H"
+
+#define SBE_TEMP_DUMP_FILE "/tmp/trace_dump.bin"
+#define SBE_TRACE_BIN "/tmp/sbe_trace.bin"
+#define PPE2FSP_TOOL "ppe2fsp"
+#define P9_XIP_TOOL "p9_xip_tool"
+#define SBE_TRACE_CMD "fsp-trace -s"
+#define SBE_TRACE_HEADLINE "SBE Traces"
+#define SBE_ATTR_DUMP_HEADLINE "SBE Attributes Dump"
+#define P9_XIP_ATTR_CMD "-ifs attrdump"
+#define SBE_STRING_FILE "sbeStringFile"
+#define SBE_SEEPROM_BIN "sbe_seeprom.bin"
+
+#define SBE_PARSER_MAX_LOCAL_BUFFER 8192
+
+#define SBE_PARSER_PRINT_DELIMITER {std::cout << \
+"*****************************************************************************"\
+<< std::endl;}
+#define SBE_PARSER_PRINT_HEADING(x) { SBE_PARSER_PRINT_DELIMITER \
+std::cout << \
+" "x<< std::endl;\
+SBE_PARSER_PRINT_DELIMITER }
+
+std::string findSbeFile(const char *name)
+{
+#ifdef CONTEXT_x86_nfp
+ //TODO via RTC:157433
+ std::string tmp = getenv("bb");
+ tmp += "obj/x86.nfp/sbei/sbfw/img/";
+ std::string file = tmp + name;
+
+ struct stat l_stat;
+ if(stat(file.c_str(), &l_stat) < 0)
+ {
+ //Can't find the file
+ }
+
+ return file;
+#endif
+#ifdef CONTEXT_ppc
+ std::string tmp = getenv("PATH");
+ tmp += ":/nfs:/maint";
+
+ char *path = strdup(tmp.c_str());
+ char *dir = NULL;
+
+ std::string file;
+
+ struct stat l_stat;
+
+ for(dir = strtok( path, ":" ); dir; dir = strtok(NULL, ":"))
+ {
+ file = file + dir + "/" + name;
+
+ if(stat(file.c_str(), &l_stat) < 0)
+ {
+ // String file not found, go to next one
+ file.clear();
+ }
+ else
+ {
+ // update where trexStringFile is
+ break;
+ }
+ }
+
+ free(path);
+ path = NULL; //sm05c
+
+ return file;
+#endif
+}
+
+void sbeParserSysCall(const char *cmd)
+{
+ FILE *stream;
+ char buffer[256];
+
+ stream = popen(cmd, "r" );
+ if(stream)
+ {
+ while(!feof(stream))
+ {
+ if(fgets(buffer, 256, stream) != NULL)
+ {
+ std::cout << buffer;
+ }
+ }
+ }
+ else
+ {
+ std::cout << "command failed :[" << cmd << "]" << std::endl;
+ std::cout << "errno [" << errno << "]" << std::endl;
+ }
+}
+
+int parseSbeFFDC(ErrlUsrParser & i_parser, const void * i_pBuffer,
+ const uint32_t i_buflen)
+{
+ int l_rc = 0;
+ uint32_t fapiRc = 0;
+ sbeFFDCDataHeader_t l_pData = {0};
+ char l_buffer[SBE_PARSER_MAX_LOCAL_BUFFER] = {0};
+ char *l_pBuffer = (char*)i_pBuffer;
+ uint32_t l_buflen = i_buflen;
+
+ do
+ {
+ if(i_pBuffer == NULL)
+ {
+ l_rc = -1;
+ break;
+ }
+ //seek l_mem to the binary blob of FFDC package
+ UtilMem l_mem(const_cast<void*>(i_pBuffer),i_buflen);
+
+ // The data is a buffer of SBE FFDC data
+ i_parser.PrintHeading("SBE FFDC Parser");
+
+ if(l_buflen < sizeof(fapiRc))
+ {
+ i_parser.PrintHexDump(l_pBuffer, l_buflen);
+ break;
+ }
+ l_buflen -= sizeof(fapiRc);
+ l_pBuffer += sizeof(fapiRc);
+ l_mem >> fapiRc;
+ i_parser.PrintNumber("FAPI RC ", "0x%08X", fapiRc);
+
+ if(l_buflen < sizeof(l_pData))
+ {
+ i_parser.PrintHexDump(l_pBuffer, l_buflen);
+ break;
+ }
+ l_buflen -= sizeof(l_pData);
+ l_pBuffer += sizeof(l_pData);
+ l_mem >> l_pData;
+
+ i_parser.PrintNumber("Primary Status ", "0x%04X",
+ (uint16_t)l_pData.primaryStatus);
+ i_parser.PrintNumber("Secondary Status ", "0x%04X",
+ (uint16_t)l_pData.secondaryStatus);
+
+ //loop through the number of fields configured
+ uint32_t l_dumpFields = l_pData.dumpFields.get();
+ while(l_dumpFields && !l_rc)
+ {
+ if(l_dumpFields & 0x0001)
+ {
+ if(l_buflen < sizeof(uint32_t))
+ {
+ //Complete this loop and let the tools print as much data
+ //as possible but break from next loop
+ l_rc = -1;
+ }
+ sbeFFDCUserDataIdentifier_t l_ffdcUserDataId = {0};
+ l_buflen -= sizeof(uint32_t); //l_ffdcUserDataId
+ l_pBuffer += sizeof(uint32_t); //l_ffdcUserDataId
+
+ l_mem >> l_ffdcUserDataId;
+
+ // TODO via RTC:158462 continue even for attribute dump
+ // Need to extend p9_xip_tool for partial attr dump handling
+ if((l_buflen < l_ffdcUserDataId.fieldLen) &&
+ (l_ffdcUserDataId.fieldId != SBE_FFDC_TRACE_DUMP))
+ {
+ i_parser.PrintHexDump(l_pBuffer, l_buflen);
+ break;
+ }
+
+ l_buflen -= l_ffdcUserDataId.fieldLen;
+ l_pBuffer += l_ffdcUserDataId.fieldLen;
+
+ l_mem.read(l_buffer, l_ffdcUserDataId.fieldLen);
+ std::ostringstream l_strFile;
+ //Generate temp dump file name
+ l_strFile << SBE_TEMP_DUMP_FILE;
+
+ //Write dump into the temporary file
+ UtilFile l_fileObj(l_strFile.str().c_str());
+ errlHndl_t l_errlHndl = l_fileObj.open("w");
+ if ( l_errlHndl )
+ {
+ std::cerr << "Error opening "
+ << l_strFile.str() << std::endl;
+ l_errlHndl->commit(HWSV_COMP_ID, ERRL_ACTION_REPORT);
+ delete l_errlHndl;
+ l_errlHndl = NULL;
+ i_parser.PrintHexDump(l_buffer, l_ffdcUserDataId.fieldLen);
+ return -1;
+ }
+ else
+ {
+ l_fileObj.write( l_buffer, l_ffdcUserDataId.fieldLen);
+ l_fileObj.Close();
+ }
+
+ //Specific handling
+ if(l_ffdcUserDataId.fieldId == SBE_FFDC_ATTR_DUMP)
+ {
+ SBE_PARSER_PRINT_HEADING(SBE_ATTR_DUMP_HEADLINE)
+ //command
+ std::ostringstream l_strCmd1;
+ // p9_xip_tool <sbe seeprom bin file>
+ // -ifs attrdump <attr dump file> 2>&1
+ l_strCmd1 << findSbeFile(P9_XIP_TOOL)
+ << " "
+ << findSbeFile(SBE_SEEPROM_BIN)
+ << " "
+ << P9_XIP_ATTR_CMD
+ << " "
+ << l_strFile.str().c_str()
+ << " "
+ << "2>&1";
+
+ //Call out the command
+ sbeParserSysCall( l_strCmd1.str().c_str() );
+ }
+ else if(l_ffdcUserDataId.fieldId == SBE_FFDC_TRACE_DUMP)
+ {
+ SBE_PARSER_PRINT_HEADING(SBE_TRACE_HEADLINE)
+ //command
+ std::ostringstream l_strCmd1, l_strCmd2;
+ // ppe2fsp <trace dump file> <trace bin file> 2>&1
+ l_strCmd1 << findSbeFile(PPE2FSP_TOOL)
+ << " "
+ << l_strFile.str().c_str()
+ << " "
+ << SBE_TRACE_BIN
+ << " "
+ << "2>&1";
+
+ // fsp-trace -s <sbe string file> <trace bin file> 2>&1
+ l_strCmd2 << SBE_TRACE_CMD
+ << " "
+ << findSbeFile(SBE_STRING_FILE)
+ << " "
+ << SBE_TRACE_BIN
+ << " "
+ << "2>&1";
+
+ //Call out the commands
+ sbeParserSysCall( l_strCmd1.str().c_str() );
+ sbeParserSysCall( l_strCmd2.str().c_str() );
+ }
+
+ //Delete the temp file
+ l_fileObj.Remove();
+ }
+ l_dumpFields >>= 1;
+ if(l_rc != 0)
+ {
+ break;
+ }
+ }
+ } while(false);
+
+ return l_rc;
+}
diff --git a/src/sbefw/pool.C b/src/sbefw/pool.C
new file mode 100644
index 00000000..6695135a
--- /dev/null
+++ b/src/sbefw/pool.C
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/pool.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <stdint.h>
+#include <sbetrace.H>
+#include <stddef.h>
+#include<pool.H>
+#include "assert.h"
+
+namespace SBEVECTORPOOL
+{
+
+vectorMemPool_t g_pool[G_POOLSIZE];
+
+vectorMemPool_t * allocMem()
+{
+ vectorMemPool_t *pool = NULL;
+ for( size_t idx = 0; idx < G_POOLSIZE; idx++ )
+ {
+ if( 0 == g_pool[idx].refCount )
+ {
+ pool = g_pool + idx;
+ g_pool[idx].refCount++;
+ break;
+ }
+ }
+ SBE_DEBUG(" Giving pool 0x%08X", pool);
+ return pool;
+}
+
+void releaseMem( vectorMemPool_t * i_pool )
+{
+ do
+ {
+ if ( NULL == i_pool ) break;
+
+ // Assert here. This pool was not supposed to be in use.
+ assert( 0 != i_pool->refCount )
+ SBE_DEBUG(" Releasing pool 0x%08X", i_pool);
+ i_pool->refCount--;
+ SBE_DEBUG(" In releaseMem() RefCount:%u", i_pool->refCount);
+ }while(0);
+}
+
+} // namesspace SBEVECTORPOOL
diff --git a/src/sbefw/pool.H b/src/sbefw/pool.H
new file mode 100644
index 00000000..3968852c
--- /dev/null
+++ b/src/sbefw/pool.H
@@ -0,0 +1,58 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/pool.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef SBE_VECTOR_POOL_H
+#define SBE_VECTOR_POOL_H
+
+namespace SBEVECTORPOOL
+{
+
+// Size of a block for a vector
+static const size_t G_BLOCKSIZE = 512;
+
+//Pool size
+static const size_t G_POOLSIZE = 4;
+
+typedef struct
+{
+ size_t refCount;
+ uint8_t data[G_BLOCKSIZE] __attribute__ ((aligned (8)));
+}vectorMemPool_t;
+
+/**
+ * @brief Returns memory pool block.
+ *
+ * @return Memory block if available, NULL otherwise.
+ */
+vectorMemPool_t * allocMem();
+
+/**
+ * @brief Release memory pool block.
+ *
+ * @param[in] i_pool pool pointer.
+ */
+void releaseMem( vectorMemPool_t * i_pool );
+
+} // namespace SBEVECTORPOOL
+#endif //SBE_VECTOR_POOL_H
diff --git a/src/sbefw/sbeFFDC.C b/src/sbefw/sbeFFDC.C
new file mode 100644
index 00000000..88bee00d
--- /dev/null
+++ b/src/sbefw/sbeFFDC.C
@@ -0,0 +1,141 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeFFDC.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "sbefifo.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeFifoMsgUtils.H"
+#include "sberegaccess.H"
+#include "sbeFFDC.H"
+
+/*
+ * @brief sendOverFIFO - method to pack and send SBE internal FFDC
+ * only if isSendInternalFFDCSet() is true
+ * over FIFO interface
+ * @param[in] i_primStatus - Primary status of Chip op
+ * @param[in] i_secStatus - Secondary status of Chip op
+ * @param[in] i_fieldsConfig - bitmap indicating the field
+ * to be sent in FFDC
+ *
+ * @param[out] o_bytesSent -number of bytes sent
+ *
+ * @return - SBE secondary RC
+ */
+uint32_t SbeFFDCPackage::sendOverFIFO(uint32_t i_primStatus,
+ uint32_t i_secStatus,
+ uint32_t i_fieldsConfig,
+ uint32_t &o_bytesSent)
+{
+ #define SBE_FUNC "sbeSendFFDCPackageFIFO "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t length = 0;
+
+ do
+ {
+ //reset sent bytes
+ o_bytesSent = 0;
+
+ //check if SBE internal FFDC should be generated
+ if(SbeRegAccess::theSbeRegAccess().isSendInternalFFDCSet() == false)
+ {
+ SBE_INFO(SBE_FUNC" isSendInternalFFDCSet()=false, "
+ "not generating SBE InternalFFDC");
+ rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+
+ // update the primary and secondary status
+ iv_sbeFFDCDataHeader.primaryStatus = i_primStatus;
+ iv_sbeFFDCDataHeader.secondaryStatus = i_secStatus;
+ //Update the user data header with dump fields configuration
+ iv_sbeFFDCDataHeader.dumpFields.set(i_fieldsConfig);
+ iv_sbeFFDCHeader.lenInWords = (sizeof(sbeResponseFfdc_t) +
+ sizeof(sbeFFDCDataHeader_t))
+ /sizeof(uint32_t);
+ //Update the length in ffdc package header base on required fields
+ for(auto &sbeFFDCUserData:sbeFFDCUserDataArray)
+ {
+ if(sbeFFDCUserData.userDataId.fieldId & i_fieldsConfig)
+ {
+ iv_sbeFFDCHeader.lenInWords +=
+ (sbeFFDCUserData.userDataId.fieldLen +
+ sizeof(sbeFFDCUserDataIdentifier_t))
+ /sizeof(uint32_t);
+ }
+ }
+
+ //Send FFDC package header
+ length = sizeof(iv_sbeFFDCHeader) / sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult(length,
+ (uint32_t *)(&(iv_sbeFFDCHeader)));
+ if( rc!= SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ o_bytesSent += length;
+
+ //Send FFDC user data header
+ length = sizeof(iv_sbeFFDCDataHeader) / sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult(length,
+ (uint32_t *)(&(iv_sbeFFDCDataHeader)));
+ if( rc!= SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ o_bytesSent += length;
+
+ //Send FFDC user data blobs
+ for(auto &sbeFFDCUserData:sbeFFDCUserDataArray)
+ {
+ if(sbeFFDCUserData.userDataId.fieldId & i_fieldsConfig)
+ {
+ //Send User data identifer and length
+ length = sizeof(sbeFFDCUserDataIdentifier_t) / sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult(length,
+ (uint32_t*)&(sbeFFDCUserData.userDataId));
+ if( rc!= SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ o_bytesSent += length;
+
+ //Send User data
+ length = sbeFFDCUserData.userDataId.fieldLen / sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult(length,
+ (uint32_t*)sbeFFDCUserData.userDataPtr);
+ if( rc!= SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ o_bytesSent += length;
+ }
+ }
+
+ SBE_INFO(SBE_FUNC "Number of words sent [%d]", o_bytesSent);
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
diff --git a/src/sbefw/sbeFFDC.H b/src/sbefw/sbeFFDC.H
new file mode 100644
index 00000000..514b9caf
--- /dev/null
+++ b/src/sbefw/sbeFFDC.H
@@ -0,0 +1,125 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeFFDC.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SBE_FFDC_H
+#define __SBE_FFDC_H
+
+#include "fapi2.H"
+#include "plat_attributes.H"
+#include "pk_trace.h"
+#include "sbeFFDCType.H"
+#include "sbeSpMsg.H"
+
+//PIBMEM attribute dump
+extern G_sbe_attrs_t G_sbe_attrs;
+
+//Configuration of user data blobs present in SBE FFDC
+//Data is sent in the order defined here
+//Definition - Identifier
+// length of the blob
+// pointer to the data
+const sbeFFDCUserData_t sbeFFDCUserDataArray[] =
+ {{{SBE_FFDC_TRACE_DUMP,
+ sizeof(PkTraceBuffer)},
+ (const void *)&g_pk_trace_buf,
+ },
+ {{SBE_FFDC_ATTR_DUMP,
+ sizeof(G_sbe_attrs_t)},
+ (const void *)&G_sbe_attrs,
+ },
+ };
+
+//SBE internal FFDC package class
+class SbeFFDCPackage
+{
+private:
+ //Disable copy constructor
+ SbeFFDCPackage(SbeFFDCPackage const &) = delete;
+ //Disable assignment operator
+ SbeFFDCPackage& operator=(SbeFFDCPackage const &) = delete;
+
+ sbeResponseFfdc_t iv_sbeFFDCHeader;
+ //FFDC user data header
+ sbeFFDCDataHeader_t iv_sbeFFDCDataHeader;
+
+public:
+ /*ctor
+ *
+ */
+ SbeFFDCPackage()
+ {
+ //Making sure data is indeed aligned
+ static_assert((sizeof(G_sbe_attrs_t) % 4) == 0,
+ "G_sbe_attrs not 4byte aligned");
+ static_assert((sizeof(PkTraceBuffer) % 4) == 0,
+ "g_pk_trace_buf not 4byte aligned");
+
+ iv_sbeFFDCHeader.magicBytes = 0xFFDC;
+ iv_sbeFFDCHeader.fapiRc = fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+ iv_sbeFFDCDataHeader.primaryStatus = SBE_PRI_OPERATION_SUCCESSFUL;
+ iv_sbeFFDCDataHeader.secondaryStatus = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ //length and dumpFields will be filled up depending on the fields
+ //to be sent in send APIs
+ iv_sbeFFDCDataHeader.dumpFields = {0};
+ }
+ /*
+ * @brief sendOverFIFO - method to pack and send SBE internal FFDC
+ * only if isSendInternalFFDCSet() is true
+ * over FIFO interface
+ * @param[in] i_primStatus - Primary status of Chip op
+ * @param[in] i_secStatus - Secondary status of Chip op
+ * @param[in] i_fieldsConfig - bitmap indicating the field
+ * to be sent in FFDC
+ *
+ * @param[out] o_bytesSent -number of bytes sent
+ *
+ * @return - SBE secondary RC
+ */
+ uint32_t sendOverFIFO(uint32_t i_primStatus,
+ uint32_t i_secStatus,
+ uint32_t i_fieldsConfig,
+ uint32_t &o_bytesSent);
+
+ /* TODO via RTC:150786
+ * @brief sendOverHOST - method to pack and send SBE internal FFDC
+ * only if isSendInternalFFDCSet() is true
+ * over HOST interface
+ *
+ * @param[in] i_primStatus - Primary status of Chip op
+ * @param[in] i_secStatus - Secondary status of Chip op
+ * @param[in] i_fieldsConfig - bitmap indicating the field
+ * to be sent in FFDC
+ *
+ * @param[out] o_bytesSent - number of bytes sent
+ *
+ * @return - SBE secondary RC
+ */
+ //uint32_t sendOverHOST(uint32_t i_primStatus,
+ // uint32_t i_secStatus,
+ // uint32_t i_fieldsConfig,
+ // uint32_t &o_bytesSent) {};
+};
+
+#endif //__SBE_FFDC_H
diff --git a/src/sbefw/sbeFFDCType.H b/src/sbefw/sbeFFDCType.H
new file mode 100644
index 00000000..f4ef95ad
--- /dev/null
+++ b/src/sbefw/sbeFFDCType.H
@@ -0,0 +1,100 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeFFDCType.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SBE_FFDC_TYPE_H
+#define __SBE_FFDC_TYPE_H
+
+//Bit mapped identifiers
+#define SBE_FFDC_ATTR_DUMP 0x0001
+#define SBE_FFDC_TRACE_DUMP 0x0002
+#define SBE_FFDC_ALL_DUMP 0xFFFF
+
+/* Structure indicating the contents of FFDC package
+ * value 'true' - field present;value 'false' - field not present
+ * bit_0 - attribute dump
+ * bit_1 - trace buffer dump
+ * bit 2-31 - reserved
+ */
+typedef struct
+{
+ uint32_t attrField:1;
+ uint32_t traceField:1;
+ uint32_t reserved:30;
+ /* @breif - set dump fields
+ *
+ * @param[in] - uint32_t value to be updated
+ */
+ void set(uint32_t val)
+ {
+ if(val & SBE_FFDC_ATTR_DUMP)
+ {
+ attrField = true;
+ }
+ if(val & SBE_FFDC_TRACE_DUMP)
+ {
+ traceField = true;
+ }
+ }
+ /* @brief - get dump fields as uint32_t
+ *
+ * @return - uint32_t value
+ */
+ uint32_t get()
+ {
+ uint32_t l_val = 0;
+ if(attrField)
+ {
+ l_val |= SBE_FFDC_ATTR_DUMP;
+ }
+ if(traceField)
+ {
+ l_val |= SBE_FFDC_TRACE_DUMP;
+ }
+ return l_val;
+ }
+} sbeFFDCDumpFields_t;
+
+//Sturcture indicating the type of ffdc user data blob
+//and its length in bytes
+typedef struct
+{
+ uint32_t fieldId:16;
+ uint32_t fieldLen:16;
+} sbeFFDCUserDataIdentifier_t;
+
+//Structure of ffdc user data blob
+typedef struct
+{
+ sbeFFDCUserDataIdentifier_t userDataId;
+ const void *userDataPtr;
+} sbeFFDCUserData_t;
+
+//keep it packed to 4byte boundary to avoid packing bytes
+typedef struct
+{
+ uint32_t primaryStatus:16;//Chip Op Primary status
+ uint32_t secondaryStatus:16;//Chip Op Secondary status
+ sbeFFDCDumpFields_t dumpFields;//bitmapped dumpFields
+} sbeFFDCDataHeader_t;
+
+#endif //__SBE_FFDC_TYPE_H
diff --git a/src/sbefw/sbeFifoMsgUtils.C b/src/sbefw/sbeFifoMsgUtils.C
new file mode 100644
index 00000000..99cf2709
--- /dev/null
+++ b/src/sbefw/sbeFifoMsgUtils.C
@@ -0,0 +1,375 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeFifoMsgUtils.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbeFifoMsgUtils.C
+ *
+ * @brief This file contains the SBE FIFO Access Common Utility Functions
+ *
+ */
+
+#include "sbefifo.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeFifoMsgUtils.H"
+#include "sbeerrorcodes.H"
+#include "assert.h"
+#include "sbeFFDC.H"
+
+// If we can not perform FIFO operation ( FIFO FULL while writing
+// or EMPTY while reading ) we will sleep for FIFO_WAIT_SLEEP_TIME
+// ms so that FIFO can be ready.
+static const uint32_t FIFO_WAIT_SLEEP_TIME = 1;
+// Write this data to send EOT to DS FIFO. The register to send EOT
+// is 32 bit only. But our scom operations are 64 bit. So set a bit
+// in higher word to trigger EOT.
+static const uint64_t DOWNSTREAM_EOT_DATA = 0x100000000ull;
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeUpFifoDeq_mult (uint32_t &io_len,
+ uint32_t *o_pData,
+ const bool i_isEotExpected,
+ const bool i_flush)
+{
+ #define SBE_FUNC " sbeUpFifoDeq_mult "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t l_len = 0;
+
+ // If Caller didn't request flush operation
+ // and passed a non-zero valid length, we
+ // would expect a valid buffer
+ if ((!i_flush) && (io_len > 0))
+ {
+ assert ( NULL != o_pData)
+ }
+
+ do
+ {
+ sbeFifoEntry_t l_data = {0};
+
+ // Read Double word from the Upstream FIFO;
+ // The DW data represents the first 32 bits of data word entry
+ // followed by the status bits.
+
+ // Bit 0-31 : Data
+ // Bit 32 : Data valid flag
+ // Bit 33 : EOT flag
+ // Bit 34-63 : Status (2-31)
+ // Valid : EOT
+ // 1 : 0 -> data=message
+ // 0 : 1 -> data=dummy_data of EOT operation
+ // 0 : 0 -> data=dummy_data
+ // 1 : 1 -> Not used
+
+ l_rc = sbeUpFifoDeq ( reinterpret_cast<uint64_t*>(&l_data) );
+
+ if (l_rc)
+ {
+ // Error while dequeueing from upstream FIFO
+ SBE_ERROR(SBE_FUNC"sbeUpFifoDeq failed,"
+ "l_rc=[0x%08X]", l_rc);
+ // @TODO RTC via : 132295
+ // RC refactoring - reserve 3 bits in SBE RC for PCBPIB
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ SBE_DEBUG(SBE_FUNC"sbeUpFifoDeq, "
+ "l_data.fifo_data=[0x%08X],",
+ l_data.fifo_data);
+
+ // If FIFO reset is requested
+ if(l_data.statusOrReserved.req_upfifo_reset)
+ {
+ // @TODO via RTC : 126147
+ // Review reset loop flow in here.
+ // Received a FIFO reset request
+ l_rc = SBE_FIFO_RESET_RECEIVED;
+ break;
+ }
+
+ // if EOT flag is set, clear EOT and
+ // set the RC accordingly
+ if (l_data.statusOrReserved.eot_flag)
+ {
+ l_rc = sbeUpFifoAckEot();
+ if (l_rc)
+ {
+ // Error while ack'ing EOT in upstream FIFO
+ SBE_ERROR(SBE_FUNC"sbeUpFifoAckEot failed,"
+ "l_rc=[0x%08X]", l_rc);
+
+ // Collect FFDC and save off the l_rc
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ // Successfully Ack'ed the EOT in upstream FIFO
+ if ( ((!i_isEotExpected) || (l_len != io_len))
+ && (!i_flush) )
+ {
+ if (l_len < io_len)
+ {
+ // Unexpected EOT, got insufficient data
+ l_rc = SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA ;
+ }
+ else
+ {
+ // Unexpected EOT, got excess data
+ l_rc = SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA ;
+ }
+ }
+ break;
+ }
+
+ // if Upstream FIFO is empty,
+ if (l_data.statusOrReserved.fifo_empty)
+ {
+ pk_sleep(PK_MILLISECONDS(FIFO_WAIT_SLEEP_TIME));
+ continue;
+ }
+
+ if ((!i_flush) && (l_len < io_len))
+ {
+ o_pData[l_len] = l_data.fifo_data;
+ }
+
+ ++l_len;
+
+ } while(i_flush || i_isEotExpected || (l_len < io_len));
+
+ // Return the length of entries dequeued.
+ io_len = l_len;
+ return l_rc;
+
+ #undef SBE_FUNC
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeDownFifoEnq_mult (uint32_t &io_len,
+ const uint32_t *i_pData)
+{
+ #define SBE_FUNC " sbeDownFifoEnq_mult "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t l_len = 0;
+
+ do
+ {
+ sbeDownFifoStatusReg_t l_status = {0};
+
+ // Read the down stream FIFO status
+ l_rc = sbeDownFifoGetStatus (reinterpret_cast<uint64_t *>(&l_status));
+ if (l_rc)
+ {
+ // Error while reading downstream FIFO status
+ SBE_ERROR(SBE_FUNC"sbeDownFifoGetStatus failed, "
+ "l_rc=[0x%08X]", l_rc);
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ // Check if there was a FIFO reset request from SP
+ if (l_status.downfifo_status.req_upfifo_reset)
+ {
+ // @TODO via RTC : 126147
+ // Review reset loop flow in here.
+ // Received an upstream FIFO reset request
+ SBE_ERROR(SBE_FUNC"Received reset request");
+ l_rc = SBE_FIFO_RESET_RECEIVED;
+ break;
+ }
+
+ // Check if downstream FIFO is full
+ if (l_status.downfifo_status.fifo_full)
+ {
+ // Downstream FIFO is full
+ pk_sleep(PK_MILLISECONDS(FIFO_WAIT_SLEEP_TIME));
+ continue;
+ }
+
+ // PIB write data format:
+ // Bit 0 - 31 : Data
+ // Bit 32 - 63 : Unused
+
+ sbeFifoEntry_t l_data = {0};
+
+ l_data.fifo_data = *(i_pData+l_len);
+
+ SBE_DEBUG(SBE_FUNC"Downstream fifo data entry[0x%08X]",
+ l_data.fifo_data);
+
+ // Write the data into the downstream FIFO
+ uint64_t * tp = reinterpret_cast<uint64_t*>(&l_data);
+ l_rc = sbeDownFifoEnq ( *tp );
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"sbeDownFifoEnq failed, "
+ "l_rc[0x%08X]", l_rc);
+ // @TODO RTC via : 132295
+ // RC refactoring - reserve 3 bits in SBE RC for PCBPIB
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ ++l_len;
+
+ } while(l_len<io_len);
+
+ io_len = l_len;
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////
+void sbeBuildMinRespHdr ( uint32_t *io_pBuf,
+ uint32_t &io_curIndex,
+ const uint16_t i_primStatus,
+ const uint16_t i_secStatus,
+ const uint32_t i_pcbpibStatus,
+ const uint32_t i_startIndex )
+{
+ do
+ {
+ if (!io_pBuf)
+ {
+ break;
+ }
+
+ io_pBuf[io_curIndex] = sbeBuildRespHeaderMagicCodeCmdClass();
+ io_pBuf[++io_curIndex] = sbeBuildRespHeaderStatusWordLocal(
+ i_primStatus, i_secStatus);
+
+ // Pcb-Pib error is optional,
+ // not needed for success case
+ if ( (i_primStatus != SBE_PRI_OPERATION_SUCCESSFUL) ||
+ (i_pcbpibStatus != SBE_PCB_PIB_ERROR_NONE) )
+ {
+ io_pBuf[++io_curIndex] = i_pcbpibStatus;
+ }
+
+ // Somehow this compiler isn't allowing the
+ // index pre-increment for the last array entry
+ // directly embedded into the assignment
+ ++io_curIndex;
+ io_pBuf[io_curIndex] = io_curIndex - i_startIndex + 1;
+
+ } while(false);
+}
+
+////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////
+uint32_t sbeDownFifoSignalEot (void)
+{
+ uint32_t l_rc = 0;
+ #define SBE_FUNC "sbeDownFifoSignalEot "
+ SBE_ENTER(SBE_FUNC);
+ sbeDownFifoStatusReg_t l_status = {0};
+ do
+ {
+ // Read the down stream FIFO status
+ l_rc = sbeDownFifoGetStatus (reinterpret_cast<uint64_t *>(&l_status));
+ if (l_rc)
+ {
+ // Error while reading downstream FIFO status
+ SBE_ERROR(SBE_FUNC"sbeDownFifoGetStatus failed, "
+ "l_rc=[0x%08X]", l_rc);
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ // Check if downstream FIFO is full
+ if (l_status.downfifo_status.fifo_full)
+ {
+ pk_sleep(PK_MILLISECONDS(FIFO_WAIT_SLEEP_TIME));
+ continue;
+ }
+ l_rc = putscom_abs(SBE_DOWNSTREAM_FIFO_SIGNAL_EOT, DOWNSTREAM_EOT_DATA);
+ break;
+ } while(1);
+
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
+uint32_t sbeDsSendRespHdr(const sbeRespGenHdr_t &i_hdr,
+ const sbeResponseFfdc_t &i_ffdc )
+{
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ do
+ {
+ uint32_t distance = 1; //initialise by 1 for entry count itself.
+ uint32_t len = sizeof( i_hdr )/sizeof(uint32_t);
+ // sbeDownFifoEnq_mult.
+ rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &i_hdr);
+ if (rc)
+ {
+ break;
+ }
+ distance += len;
+
+ // If no ffdc , exit;
+ if( i_ffdc.getRc() )
+ {
+ len = sizeof(i_ffdc)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &i_ffdc);
+ if (rc)
+ {
+ break;
+ }
+ distance += len;
+ }
+
+ // If there is a SBE internal failure
+ if((i_hdr.primaryStatus != SBE_PRI_OPERATION_SUCCESSFUL) ||\
+ (i_hdr.secondaryStatus != SBE_SEC_OPERATION_SUCCESSFUL))
+ {
+ //Add FFDC data as well.
+ //Generate all the fields of FFDC package
+ SbeFFDCPackage sbeFfdc;
+ rc = sbeFfdc.sendOverFIFO(i_hdr.primaryStatus,
+ i_hdr.secondaryStatus,
+ SBE_FFDC_ALL_DUMP,
+ len);
+ if (rc)
+ {
+ break;
+ }
+ distance += len;
+ }
+
+ len = sizeof(distance)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, &distance);
+ if (rc)
+ {
+ break;
+ }
+
+ }while(0);
+ return rc;
+}
diff --git a/src/sbefw/sbeFifoMsgUtils.H b/src/sbefw/sbeFifoMsgUtils.H
new file mode 100644
index 00000000..60492964
--- /dev/null
+++ b/src/sbefw/sbeFifoMsgUtils.H
@@ -0,0 +1,192 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeFifoMsgUtils.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbeFifoMsgUtils.H
+ *
+ * @brief This file contains the SBE FIFO Access Common Utility Functions
+ *
+ */
+
+#ifndef __SBEFW_SBEFIFOMSGUTILS_H
+#define __SBEFW_SBEFIFOMSGUTILS_H
+
+#include <stdint.h>
+#include "sbeexeintf.H"
+
+
+/**********************************************************************/
+// SBE Utilities
+/**********************************************************************/
+
+/**
+ * @brief sbeUpFifoDeq_mult : Dequeue multiple entries from upstream FIFO
+ *
+ * @param[in/out] io_len
+ * On input: Non-zero number of entries (excluding EOT) to dequeue.
+ * Ignored when i_flush == true.
+ * On output: Number of entries dequeued (excluding EOT).
+ * @param[out] o_pData Entries dequeued into the buffer
+ * @param[in] i_isEotExpected true / false
+ * true - Default case.
+ * Caller expects an EOT entry after io_len entries are
+ * dequeued. Accordingly, this function will attempt to dequeue
+ * the EOT entry after io_len entries are dequeued.
+ * false - Caller doesn't expect an EOT after io_len entries are
+ * dequeued. Accordingly, this function will not attempt to
+ * dequeue the EOT entry after io_len entries are dequeued.
+ * @param[in] i_flush true / false
+ * true - caller requested FIFO flush
+ * Usually caller marks this flag as true to handle error scenario.
+ * All entries written in the US fifo (until an EOT is encountered),
+ * would be dequeued and discarded (not processed). Note that io_len
+ * and i_isEotExpected inputs are ignored in this case.
+ * However, flag i_isEotExpected is always interpreted as true in
+ * case.
+ * false - Default good path.
+ * US Fifo entries will be dequeued and processed per inputs io_len
+ * and i_isEotExpected.
+ *
+ * @return Return Code SUCCESS or a secondary response code
+ * SBE_SEC_OPERATION_SUCCESSFUL
+ * SBE_SEC_FIFO_ACCESS_FAILURE
+ * SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA
+ * SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA
+ * SBE_FIFO_RESET_RECEIVED
+ *
+ */
+extern uint32_t sbeUpFifoDeq_mult (uint32_t &io_len,
+ uint32_t *o_pData,
+ const bool i_isEotExpected = true,
+ const bool i_flush = false);
+
+
+/**
+ * @brief sbeDownFifoEnq_mult : Enqueue into downstream FIFO
+ *
+ * @param[in/out] io_len number of entries to enqueue as input,
+ * number of entries enqueued as output
+ * @param[in] i_pData buffer containting data to be enqueued
+ *
+ * @return Rc SUCCESS or a secondary response code
+ * SBE_SEC_OPERATION_SUCCESSFUL
+ * SBE_SEC_FIFO_ACCESS_FAILURE
+ * SBE_FIFO_RESET_RECEIVED
+ *
+ */
+extern uint32_t sbeDownFifoEnq_mult (uint32_t &io_len,
+ const uint32_t *i_pData) ;
+
+
+/**
+ * @brief sbeBuildRespHeaderMagicCodeCmdClass
+ * Builds the header word containing the magic code,
+ * the command class and the opcode
+ *
+ * @return Returns the header word in the response header
+ * containing the magic code, command class and opcode
+ *
+ */
+extern inline uint32_t sbeBuildRespHeaderMagicCodeCmdClass (void)
+{
+ return ( (0xC0DE0000) |
+ (uint32_t)(g_sbeFifoCmdHdr.cmdClass << 8) |
+ (uint32_t)(g_sbeFifoCmdHdr.command));
+}
+
+/**
+ * @brief sbeBuildRespHeaderStatusWordGlobal
+ * Builds the status header word from global variables
+ *
+ * @return Returns the status word in the response header
+ *
+ */
+extern inline uint32_t sbeBuildRespHeaderStatusWordGlobal (void)
+{
+ return ( (((uint32_t)g_sbeCmdRespHdr.prim_status)<<16) |
+ (g_sbeCmdRespHdr.sec_status) );
+}
+
+/**
+ * @brief sbeBuildRespHeaderStatusWordLocal
+ * Builds the status header word from passed in parameters
+ *
+ * @param[in] const uint16_t i_primStatus Primary Response Status Code
+ * @param[in] const uint16_t i_secStatus Secondary Response Status Code
+ *
+ * @return Returns the status word in the response header
+ *
+ */
+extern inline uint32_t sbeBuildRespHeaderStatusWordLocal (
+ const uint16_t i_primStatus,
+ const uint16_t i_secStatus)
+{
+ return ( (((uint32_t)i_primStatus)<<16) | (i_secStatus) );
+}
+
+/**
+ * @brief sbeBuildMinRespHdr : Builds minimum response header
+ *
+ * @desc This builds the buffer with the following status words
+ * - Magic Bytes, Command Class, Command opcode
+ * - Primary Status Code, Secondary Status Code
+ * - PCB / PIB Status Code [optional]
+ * - Distance to Status Header
+ * @param[in/out] uint32_t *io_pBuf Buffer to be filled in
+ * @param[in/out] uint32_t &io_curIndex Current Index into the buffer
+ * @param[in] const uint16_t i_primStatus Primary Response Status Code
+ * @param[in] const uint16_t i_secStatus Secondary Response Status Code
+ * @param[in] const uint32_t i_pcbpibStatus PCB-PIB Response Status Code
+ * @param[in] const uint32_t i_startIndex Starting Index into the buffer
+ */
+
+void sbeBuildMinRespHdr ( uint32_t *io_pBuf,
+ uint32_t &io_curIndex,
+ const uint16_t i_primStatus,
+ const uint16_t i_secStatus,
+ const uint32_t i_pcbpibStatus,
+ const uint32_t i_startIndex = 0 );
+
+/**
+ * @brief sbeDownFifoSignalEot : Signal EOT in Downstream FIFO
+ *
+ * @return Rc from the underlying scom utility
+ *
+ * @note This is a blocking call. If FIFO is full, it will wait
+ * in loop ( sleep ) till the time there is some space in
+ * FIFO.
+ */
+uint32_t sbeDownFifoSignalEot (void);
+
+/**
+ * @brief sbeDsSendRespHdr : Send response header to DS FIFO
+ * - This also sends the FFDC if exist.
+ *
+ * @param[in] i_hdr Response Header
+ * @param[in] i_ffdc FFDC object
+ *
+ * @return Rc from the underlying scom utility
+ */
+uint32_t sbeDsSendRespHdr(const sbeRespGenHdr_t &i_hdr,
+ const sbeResponseFfdc_t &i_ffdc );
+#endif // __SBEFW_SBEFIFOMSGUTILS_H
diff --git a/src/sbefw/sbeHostMsg.H b/src/sbefw/sbeHostMsg.H
new file mode 100644
index 00000000..3467d59c
--- /dev/null
+++ b/src/sbefw/sbeHostMsg.H
@@ -0,0 +1,132 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeHostMsg.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbeHostMsg.H
+ *
+ * @brief This file contains the message structures for SBE Host
+ * communication.
+ *
+ */
+
+#ifndef __SBEFW_SBEHOST_MSG_H
+#define __SBEFW_SBEHOST_MSG_H
+
+#include <stdint.h>
+#include "sbe_host_intf.H"
+#include "sbe_sp_intf.H"
+
+/*****************************************************************/
+/* SBE->PSU request structures */
+/*****************************************************************/
+
+/**
+ * @brief structure for Host->SBE command request format denoting
+ * mininum header (as of now, contained in mbx 0)
+ */
+typedef struct
+{
+ // mbxReg0
+ uint64_t res:16;
+ uint64_t flags:16;
+ uint64_t seqID:16;
+ uint64_t cmdClass:8;
+ uint64_t command:8;
+
+ /**
+ * @brief initialize the fields contained in PSU Mbx0
+ *
+ */
+ void init()
+ {
+ res = 0;
+ flags = 0;
+ seqID = 0;
+ cmdClass = SBE_PSU_CMD_CLASS_UNKNOWN;
+ command = SBE_PSU_CMD_UNKNOWN;
+ }
+} sbePsu2SbeCmdReqHdr_t;
+
+extern sbePsu2SbeCmdReqHdr_t g_sbePsu2SbeCmdReqHdr;
+
+
+/*****************************************************************/
+/* SBE->PSU response structures */
+/*****************************************************************/
+
+/**
+ * @brief SBE->Host Generic response structure
+ *
+ */
+typedef struct
+{
+ uint64_t mbxReg4;
+ uint64_t mbxReg5;
+ uint64_t mbxReg6;
+ uint64_t mbxReg7;
+} sbeSbe2PsuGenericResp_t ;
+
+/**
+ * @brief Structure for SBE->Host response header contained in
+ * mbx4 register
+ *
+ */
+typedef struct
+{
+ // mbxReg 4
+ uint64_t primStatus:16;
+ uint64_t secStatus:16;
+ uint64_t seqID:16;
+ uint64_t cmdClass:8;
+ uint64_t command:8;
+
+ /**
+ * @brief set the primary and secondary status
+ *
+ * @param[in] i_prim Primary status
+ * @param[in] i_sec Secondary status
+ *
+ */
+ void setStatus(const uint16_t i_prim, const uint16_t i_sec)
+ {
+ primStatus = i_prim;
+ secStatus = i_sec;
+ }
+
+ /**
+ * @brief initialize the response fields contained in PSU Mbx3
+ *
+ */
+ void init()
+ {
+ primStatus = SBE_PRI_OPERATION_SUCCESSFUL;
+ secStatus = SBE_SEC_OPERATION_SUCCESSFUL;
+ seqID = g_sbePsu2SbeCmdReqHdr.seqID;
+ cmdClass = g_sbePsu2SbeCmdReqHdr.cmdClass;
+ command = g_sbePsu2SbeCmdReqHdr.command;
+ }
+} sbeSbe2PsuRespHdr_t;
+
+extern sbeSbe2PsuRespHdr_t g_sbeSbe2PsuRespHdr;
+
+#endif // __SBEFW_SBEHOST_MSG_H
diff --git a/src/sbefw/sbeHostUtils.C b/src/sbefw/sbeHostUtils.C
new file mode 100644
index 00000000..3e4605d0
--- /dev/null
+++ b/src/sbefw/sbeHostUtils.C
@@ -0,0 +1,226 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeHostUtils.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbeHostUtils.C
+ *
+ * @brief This file contains the PSU Access Utility Functions
+ *
+ */
+
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeHostUtils.H"
+#include "sbeHostMsg.H"
+#include "sbe_host_intf.H"
+#include "sbeerrorcodes.H"
+#include "assert.h"
+#include "fapi2.H"
+
+
+///////////////////////////////////////////////////////////////////
+// PSU->SBE register access utilities
+///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+uint32_t sbeReadPsu2SbeMbxReg (uint32_t i_addr,
+ const uint8_t i_count,
+ uint64_t *o_pData,
+ bool i_isFinalRead)
+{
+ #define SBE_FUNC " sbeReadPsu2SbeMbxReg "
+ SBE_DEBUG(SBE_FUNC"i_count[0x%02X], i_addr=[0x%08X]", i_count, i_addr);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint8_t l_count = 0;
+
+ assert((i_count >0 ) && (NULL != o_pData))
+ assert( (SBE_HOST_PSU_MBOX_REG0 <= i_addr) &&
+ (SBE_HOST_PSU_MBOX_REG3 >= (i_addr + i_count - 1)) )
+
+ while (l_count < i_count)
+ {
+ l_rc = getscom_abs ( i_addr,
+ reinterpret_cast<uint64_t*>(&o_pData[l_count]) );
+
+ if (l_rc)
+ {
+ // Error while reading from PSU->SBE mbx register
+ SBE_ERROR(SBE_FUNC"getscom_abs failed,"
+ "l_rc=[0x%08X], i_addr=[0x%08X]",
+ l_rc, i_addr);
+ break;
+ }
+
+ SBE_DEBUG(SBE_FUNC"l_data=[0x%08X%08X]",
+ SBE::higher32BWord(o_pData[l_count]),
+ SBE::lower32BWord(o_pData[l_count]));
+ ++l_count;
+ ++i_addr;
+ }
+
+ // Set the Ack bit in SBE->PSU DB register
+ // if the message requires ack and if its a final read operation
+ if ((i_isFinalRead) && (SBE_SEC_OPERATION_SUCCESSFUL == l_rc))
+ {
+ l_rc = sbeAcknowledgeHost();
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC " Failed to Sent Ack to Host over "
+ "SBE_SBE2PSU_DOORBELL_SET_BIT1");
+ }
+ }
+ return l_rc;
+
+ #undef SBE_FUNC
+}
+
+///////////////////////////////////////////////////////////////////
+// SBE->PSU register access utilities
+///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+uint32_t sbeIntrHostUponRespWaiting ()
+{
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ // Interrupt the host by setting bit0 in SBE->PSU DB register
+ // if the caller requested for it.
+ if (g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_RESP_REQUIRED)
+ {
+ l_rc = sbeSetSbe2PsuDbBitX(SBE_SBE2PSU_DOORBELL_SET_BIT0);
+ }
+ return l_rc;
+}
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+uint32_t sbeAcknowledgeHost ()
+{
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ // Set the Ack bit in SBE->PSU DB register
+ // if the caller requested for it.
+ if (g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_ACK_REQUIRED)
+ {
+ l_rc = sbeSetSbe2PsuDbBitX(SBE_SBE2PSU_DOORBELL_SET_BIT1);
+ }
+ return l_rc;
+}
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+uint32_t sbeWriteSbe2PsuMbxReg (uint32_t i_addr,
+ const uint64_t *i_pData,
+ const uint8_t i_count,
+ bool i_setBit0ToIntrHB)
+{
+ #define SBE_FUNC " sbeWriteSbe2PsuMbxReg "
+ SBE_DEBUG(SBE_FUNC"i_count[0x%02X], i_addr=[0x%08X]", i_count, i_addr);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint8_t l_count = 0;
+
+ assert( (i_count >0 ) && (NULL != i_pData) )
+ assert( (SBE_HOST_PSU_MBOX_REG4 <= i_addr) &&
+ (SBE_HOST_PSU_MBOX_REG7 >= (i_addr + i_count - 1)) )
+
+ if( g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_RESP_REQUIRED )
+ {
+ while (l_count < i_count)
+ {
+ SBE_DEBUG(SBE_FUNC"l_data=[0x%08X%08X]",
+ SBE::higher32BWord(*(i_pData+l_count)),
+ SBE::lower32BWord(*(i_pData+l_count)));
+
+ l_rc = putscom_abs ( i_addr, *(i_pData+l_count) );
+ if (l_rc)
+ {
+ // Error while reading from PSU->SBE mbx register
+ SBE_ERROR(SBE_FUNC"putscom_abs failed,"
+ "l_rc=[0x%08X], i_addr=[0x%08X]",
+ l_rc, i_addr);
+ break;
+ }
+
+ ++l_count;
+ ++i_addr;
+ }
+
+ if( (i_setBit0ToIntrHB) && (SBE_SEC_OPERATION_SUCCESSFUL == l_rc) )
+ {
+ // indicate the Host via Bit SBE_SBE2PSU_DOORBELL_SET_BIT0
+ l_rc = sbeSetSbe2PsuDbBitX(SBE_SBE2PSU_DOORBELL_SET_BIT0);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC " Failed to Sent Ack to Host over "
+ "SBE_SBE2PSU_DOORBELL_SET_BIT0");
+ }
+ }
+ }
+ return l_rc;
+
+ #undef SBE_FUNC
+}
+
+/* @brief - Send PSU Chip Op response
+ *
+ * @param[in] - i_sbe2PsuRespHdr - Response header
+ * @param[in] - i_fapiRc - fapi rc of the relevant hwp call
+ * @param[in/out] - io_rc - rc status of the PSU access utility
+ *
+ * @return - void
+ */
+void sbePSUSendResponse(sbeSbe2PsuRespHdr_t &i_sbe2PsuRespHdr,
+ uint32_t &i_fapiRc,
+ uint32_t &io_rc)
+{
+#define SBE_FUNC "sbePSUSendResponse"
+ do
+ {
+ // Making sure the PSU access utility is functional
+ if(io_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ // TODO via RTC:151555 Generate FFDC
+ if(i_fapiRc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ i_sbe2PsuRespHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ }
+
+ // Send the response header
+ io_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4,
+ (uint64_t*)(&i_sbe2PsuRespHdr),
+ (sizeof(i_sbe2PsuRespHdr)/sizeof(uint64_t)),
+ true);
+ if(SBE_SEC_OPERATION_SUCCESSFUL != io_rc)
+ {
+ SBE_ERROR(SBE_FUNC" Failed to write to "
+ "SBE_HOST_PSU_MBOX_REG4");
+ }
+ } while(0);
+#undef SBE_FUNC
+}
diff --git a/src/sbefw/sbeHostUtils.H b/src/sbefw/sbeHostUtils.H
new file mode 100644
index 00000000..efca6bf4
--- /dev/null
+++ b/src/sbefw/sbeHostUtils.H
@@ -0,0 +1,244 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeHostUtils.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbeHostUtils.H
+ *
+ * @brief This file contains basic SBE PSU hardware specific
+ * definitions and operations.
+ *
+ */
+
+#ifndef __SBEFW_SBEHOSTUTILS_H
+#define __SBEFW_SBEHOSTUTILS_H
+
+#include <stdint.h>
+#include "ppe42_scom.h"
+#include "sbeHostMsg.H"
+
+/**
+ * @brief SBE PSU Access register addresses
+ *
+ */
+const uint32_t SBE_HOST_PSU_BASE = 0x000D0050;
+
+const uint32_t SBE_HOST_PSU_MBOX_REG0 = SBE_HOST_PSU_BASE + 0x0000;
+const uint32_t SBE_HOST_PSU_MBOX_REG1 = SBE_HOST_PSU_BASE + 0x0001;
+const uint32_t SBE_HOST_PSU_MBOX_REG2 = SBE_HOST_PSU_BASE + 0x0002;
+const uint32_t SBE_HOST_PSU_MBOX_REG3 = SBE_HOST_PSU_BASE + 0x0003;
+const uint32_t SBE_HOST_PSU_MBOX_REG4 = SBE_HOST_PSU_BASE + 0x0004;
+const uint32_t SBE_HOST_PSU_MBOX_REG5 = SBE_HOST_PSU_BASE + 0x0005;
+const uint32_t SBE_HOST_PSU_MBOX_REG6 = SBE_HOST_PSU_BASE + 0x0006;
+const uint32_t SBE_HOST_PSU_MBOX_REG7 = SBE_HOST_PSU_BASE + 0x0007;
+
+
+const uint32_t SBE_PSU2SBE_DOORBELL_REG_RW = 0x000D0060;
+const uint32_t SBE_PSU2SBE_DOORBELL_REG_AND = 0x000D0061;
+const uint32_t SBE_PSU2SBE_DOORBELL_REG_OR = 0x000D0062;
+const uint32_t SBE_PSU2HOST_DOORBELL_REG_RW = 0x000D0063;
+const uint32_t SBE_PSU2HOST_DOORBELL_REG_AND = 0x000D0064;
+const uint32_t SBE_PSU2HOST_DOORBELL_REG_OR = 0x000D0065;
+
+
+/**
+ * @brief SBE PSU door bell register Bit definitions
+ */
+typedef enum
+{
+ // Bit 0 AND flag for PSU->SBE Doorbell Register;
+ // When this is set by the host firmware, it would trigger an
+ // interrupt to the SBE about a waiting message in the Host/SBE
+ // Mailbox Registers. SBE is responsible for clearing this
+ // bit upon being interrupted.
+ SBE_PSU2SBE_DOORBELL_CLEAR_BIT0 = 0x7FFFFFFFFFFFFFFFull,
+} sbe_psu2sbeDoorbellReg_UpdateFlags;
+
+typedef enum
+{
+ // Bit 0 OR flag for SBE->PSU Doorbell Register;
+ // When this is set by SBE, it would trigger an interrupt to host
+ // firmware about a waiting response in the Host/SBE Mailbox Registers 4-7
+ SBE_SBE2PSU_DOORBELL_SET_BIT0 = 0x8000000000000000ull,
+
+ // Bit 1 OR flag for SBE->PSU Doorbell Register;
+ // When this is set by SBE, it would trigger an interrupt to host
+ // firmware indicating that the message in Host/SBE mailbox registers 0-3
+ // has been read by SBE and is being processed
+ SBE_SBE2PSU_DOORBELL_SET_BIT1 = 0x4000000000000000ull,
+
+ // Bit 2 OR flag for SBE->PSU Doorbell Register;
+ // When this is set by SBE, it would trigger an interrupt to host
+ // firmware to trigger Stop15 exit on thread 0 on the master core.
+ // This would be used to trigger hostboot in istep 16
+ SBE_SBE2PSU_DOORBELL_SET_BIT2 = 0x2000000000000000ull,
+} sbe_sbe2psuDoorbellReg_UpdateFlags;
+
+
+/*****************************************************************/
+/** PSU->SBE register access utilities **/
+/*****************************************************************/
+
+/**
+ * @brief sbeClearPsu2SbeDbBitX : Clear given bit in PSU->SBE DB register
+ *
+ * @param[in] 64-Bit Scom Data indicating bit position to be cleared
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+inline uint32_t sbeClearPsu2SbeDbBitX (const uint64_t i_bit)
+{
+ return putscom_abs (SBE_PSU2SBE_DOORBELL_REG_AND, i_bit) ;
+}
+
+
+/**
+ * @brief sbeReadPsu2SbeDbReg : Read PSU->SBE DB register
+ *
+ * @param[out] 64-Bit Data read from PSU->SBE DB register
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+inline uint32_t sbeReadPsu2SbeDbReg (uint64_t *o_data)
+{
+ return getscom_abs (SBE_PSU2SBE_DOORBELL_REG_RW, o_data) ;
+}
+
+
+/**
+ * @brief sbeReadPsu2SbeMbxReg : Read from PSU->SBE MBX register(s)
+ *
+ * @param[in] i_addr
+ * Starting Mbx Register Address
+ * @param[in] i_count
+ * Number of Mbx registers to be read.
+ * @param[in] i_isFinalRead
+ * Indicates if its a final read operation for this chip op and
+ * internally handle the ack
+ * By default it is false.
+ * @param[out] o_pData
+ * Contents of the Mbx registers read into the buffer
+ * @return Return Code
+ * SUCCESS or TBD
+ */
+uint32_t sbeReadPsu2SbeMbxReg (uint32_t i_addr,
+ const uint8_t i_count,
+ uint64_t *o_pData,
+ bool i_isFinalRead = false);
+
+/*****************************************************************/
+/** SBE->PSU register access utilities **/
+/*****************************************************************/
+
+/**
+ * @brief sbeSetSbe2PsuDbBitX : Set Bit-X in SBE->PSU DB register
+ *
+ * @param[in] 64-Bit Scom Data indicating bit position
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+inline uint32_t sbeSetSbe2PsuDbBitX (const uint64_t i_bit)
+{
+ return putscom_abs (SBE_PSU2HOST_DOORBELL_REG_OR, i_bit) ;
+}
+
+/**
+ * @brief sbeClearSbe2PsuDbBitX : Clear Bit-X in SBE->PSU DB register
+ *
+ * @param[in] 64-Bit Scom Data indicating bit position
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+inline uint32_t sbeClearSbe2PsuDbBitX (const uint64_t i_bit)
+{
+ return putscom_abs (SBE_PSU2HOST_DOORBELL_REG_AND, i_bit) ;
+}
+
+/**
+ * @brief sbeReadSbe2PsuDbReg : Read SBE->PSU DB register
+ *
+ * @param[out] 64-Bit Data read from SBE->PSU DB register
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+inline uint32_t sbeReadSbe2PsuDbReg (uint64_t *o_data)
+{
+ return getscom_abs (SBE_PSU2HOST_DOORBELL_REG_RW, o_data) ;
+}
+
+/**
+ * @brief sbeAcknowledgeHost : Acknowldge by setting bit 1 in
+ * SBE->PSU DB register if the host had requested for an ack
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+uint32_t sbeAcknowledgeHost();
+
+/**
+ * @brief sbeIntrHostUponRespWaiting : Interrupt Host by
+ * setting bit 0 in SBE->PSU DB register if the host had
+ * requested for response
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+uint32_t sbeIntrHostUponRespWaiting();
+
+
+/**
+ * @brief sbeWriteSbe2PsuMbxReg : Write to SBE->PSU MBX register(s)
+ *
+ * @param[in] i_addr
+ * Starting Mbx Register Address
+ * @param[in] i_pData
+ * Contains the data to be written into given Mbx registers
+ * @param[in] i_count
+ * Number of Mbx registers to be written.
+ * @param[in] i_setBit0ToIntrHB
+ * Indicates whether to write Bit0 to interrupt the Host,
+ * By default it is false.
+ * @return Return Code
+ * SUCCESS or TBD
+ */
+uint32_t sbeWriteSbe2PsuMbxReg (uint32_t i_addr,
+ const uint64_t *i_pData,
+ const uint8_t i_count,
+ bool i_setBit0ToIntrHB = false);
+
+/* @brief - Send PSU Chip Op response
+ *
+ * @param[in] - i_sbe2PsuRespHdr - Response header
+ * @param[in] - i_fapiRc - fapi rc of the relevant hwp call
+ * @param[in/out] - io_rc - rc status of the PSU access utility
+ *
+ * @return - void
+ */
+void sbePSUSendResponse(sbeSbe2PsuRespHdr_t &i_sbe2PsuRespHdr,
+ uint32_t &i_fapiRc,
+ uint32_t &io_rc);
+#endif // __SBEFW_SBEHOSTUTILS_H
diff --git a/src/sbefw/sbeSpMsg.H b/src/sbefw/sbeSpMsg.H
new file mode 100644
index 00000000..c1b972bf
--- /dev/null
+++ b/src/sbefw/sbeSpMsg.H
@@ -0,0 +1,634 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeSpMsg.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbeSpMsg.H
+ *
+ * @brief This file contains the message structures for FIFO
+ * communication.
+ *
+ */
+
+#ifndef __SBEFW_SBESP_MSG_H
+#define __SBEFW_SBESP_MSG_H
+
+#include "sbe_sp_intf.H"
+
+// @NOTE Make sure all FIFO structures are 32 bit alligned ( the largest
+// member should be atleast 4 byte). It is required as in sbe fifo
+// operation we are casting these structures to uint32_t pointer. It can
+// cause alignment issue if largest member of structure is not atleast
+// 32 bit. We can use bit fields to optimize memory requirements.
+// These are two coding guidleines we will follow for this file
+// 1. All data members less than 32 bits will be bit fields
+// 2. All data members more than 32 buts will be divided into small
+// members of 32 bit each. This is required as compiler pads structure
+// to largest data member and we do not want extra padding for data
+// members gretater than 32 bits ( e.g. uint64_t )
+/**
+ * @brief Command Request Header
+ */
+typedef struct
+{
+ uint32_t len;
+ uint32_t reserved:16;
+ uint32_t cmdClass:8;
+ uint32_t command:8;
+}sbeFifoCmdReqBuf_t;
+
+extern sbeFifoCmdReqBuf_t g_sbeFifoCmdHdr;
+
+/**
+ * @brief structure for generic header for fifo response.
+ *
+ */
+typedef struct
+{
+ uint32_t magicCode:16;
+ uint32_t cmdClass:8;
+ uint32_t command:8;
+ uint32_t primaryStatus:16;
+ uint32_t secondaryStatus:16;
+
+ /**
+ * @brief set the primary and secondary status
+ *
+ * @param[in] i_prim Primary status
+ * @param[in] i_sec Secondary status
+ *
+ * @return
+ */
+ void setStatus( const uint16_t i_prim, const uint16_t i_sec)
+ {
+ primaryStatus = i_prim;
+ secondaryStatus = i_sec;
+ }
+
+ /**
+ * @brief set initial values for response header
+ *
+ * @note We did not set this in constructor as based on use case
+ * it is possible that g_sbeFifoCmdHdr does not have proper
+ * values at time of object creation.
+ *
+ */
+ void init()
+ {
+ magicCode = 0xC0DE;
+ cmdClass = g_sbeFifoCmdHdr.cmdClass;
+ command = g_sbeFifoCmdHdr.command;
+ primaryStatus = SBE_PRI_OPERATION_SUCCESSFUL;
+ secondaryStatus = SBE_SEC_OPERATION_SUCCESSFUL;
+ }
+
+}sbeRespGenHdr_t;
+
+/**
+ * @brief structure for generic Resp header with Len for fifo response.
+ *
+ */
+typedef struct
+{
+ uint32_t respLen;
+ sbeRespGenHdr_t respHdr;
+
+ /**
+ * @brief set response length
+ *
+ * @param[in] i_len Length
+ *
+ * @return
+ */
+ void setLength( const uint32_t i_len )
+ {
+ respLen = i_len;
+ }
+
+ /**
+ * @brief set initial values for response header
+ *
+ * @note We did not set this in constructor as based on use case
+ * it is possible that g_sbeCmdHdr does not have proper
+ * values at time of object creation.
+ *
+ */
+ void init()
+ {
+ respHdr.init();
+ }
+}sbeRespGenHdrWithLen_t;
+
+
+/**
+ * @brief structure for ffdc header for fifo response.
+ *
+ */
+typedef struct sbeResponseFfdc
+{
+ uint32_t magicBytes:16;
+ uint32_t lenInWords:16; // length in word( 4 byte )
+ uint32_t fapiRc;
+
+ /**
+ * @brief set rc
+ *
+ * @param[in] i_rc FAPI RC
+ *
+ * @return
+ */
+ void setRc(const uint32_t i_rc)
+ {
+ fapiRc = i_rc;
+ }
+
+ /**
+ * @brief return fapiRc
+ *
+ * @return fapiRc
+ */
+ uint32_t getRc() const
+ {
+ return fapiRc;
+ }
+
+ /**
+ * @brief constructor
+ *
+ * @param[in] i_rc FAPI RC
+ *
+ * @return
+ */
+ sbeResponseFfdc()
+ {
+ magicBytes = 0xFFDC;
+ //TODO via 129076.
+ //Need to change value for length once FFDC design is final.
+ lenInWords = ( sizeof(uint32_t ) // For magicBytes + lenInWords
+ + sizeof(fapiRc))
+ / sizeof(uint32_t);
+ fapiRc = 0;
+ }
+}sbeResponseFfdc_t;
+
+/**
+ * @brief structure for execute istep chipop (0xA101) contents.
+ *
+ */
+typedef struct
+{
+ uint32_t reserved1:8;
+ uint32_t major:8;
+ uint32_t reserved2:8;
+ uint32_t minor:8;
+}sbeIstepReqMsg_t;
+
+
+/**
+ * @brief structure for GetScom Chipop (0xA201) contents.
+ *
+ */
+typedef struct
+{
+ uint32_t hiAddr;
+ uint32_t lowAddr;
+}sbeGetScomReqMsg_t;
+
+/**
+ * @brief structure for PutScom Chipop (0xA202) contents.
+ *
+ */
+typedef struct
+{
+ uint32_t hiAddr;
+ uint32_t lowAddr;
+ uint32_t hiInputData;
+ uint32_t lowInputData;
+
+ /**
+ * @brief return 64-bit Scom data
+ *
+ * @return 64-bit Scom data
+ */
+ uint64_t getScomData()
+ {
+ uint64_t data = ((uint64_t)hiInputData << 32) | lowInputData;
+ return data;
+ }
+}sbePutScomReqMsg_t;
+
+/**
+ * @brief structure for Modify_Scom Chipop (0xA203) contents.
+ *
+ */
+typedef struct
+{
+ uint32_t reserved:24;
+ uint32_t opMode:8;
+ uint32_t hiAddr;
+ uint32_t lowAddr;
+ uint32_t hiInputData;
+ uint32_t lowInputData;
+
+ /**
+ * @brief return 64-bit modifying data
+ *
+ * @return 64-bit modifying data
+ */
+ uint64_t getModifyingData()
+ {
+ uint64_t data = ((uint64_t)hiInputData << 32) | lowInputData;
+ return data;
+ }
+}sbeModifyScomReqMsg_t;
+
+/**
+ * @brief structure for PutScom_UnderMask Chipop (0xA204) contents.
+ *
+ */
+typedef struct
+{
+ uint32_t hiAddr;
+ uint32_t lowAddr;
+ uint32_t hiInputData;
+ uint32_t lowInputData;
+ uint32_t hiMaskData;
+ uint32_t lowMaskData;
+
+ /**
+ * @brief return 64-bit input data
+ *
+ * @return 64-bit input data
+ */
+ uint64_t getInputData()
+ {
+ uint64_t data = ((uint64_t)hiInputData << 32) | lowInputData;
+ return data;
+ }
+
+ /**
+ * @brief return 64-bit input mask
+ *
+ * @return 64-bit input mask
+ */
+ uint64_t getInputMask()
+ {
+ uint64_t data = ((uint64_t)hiMaskData << 32) | lowMaskData;
+ return data;
+ }
+
+ /**
+ * @brief Determines 64-bit Scom data
+ *
+ * @param[in/out] io_scomData 64-bit scom data
+ */
+ void getScomData(uint64_t &io_scomData)
+ {
+ uint64_t l_inputMask = getInputMask();
+ uint64_t l_inputData = getInputData();
+ io_scomData = (io_scomData & (~l_inputMask))
+ | (l_inputData & l_inputMask);
+ }
+}sbePutScomUnderMaskReqMsg_t;
+
+/**
+ * @brief Structure for SBE Memory Access ChipOps (0xA401/A402)
+ *
+ */
+typedef struct
+{
+ uint32_t coreChipletId:8; //Pervasive Core Chiplet Id for PBA
+ uint32_t eccByte:8; //Ecc Override Byte from user
+ uint32_t flags:16; //Operational Flags -refer enum sbeMemoryAccessFlags
+ uint32_t addrHi; //Higher 32-Bit Memory Address
+ uint32_t addrLo; //Lower 32-Bit Memory Address
+ uint32_t len; //Length of Data in Bytes
+
+ /**
+ * @brief Calculates 64-bit PBA ADU Address
+ *
+ * @return Return 64-bit PBA ADU address
+ */
+ uint64_t getAddr() const
+ {
+ return (((uint64_t)addrHi << 32) | addrLo);
+ }
+
+ /**
+ * @brief Determines if ECC Override bit is set
+ *
+ * @return Returns True if ECC Override bit is set
+ * False if ECC Override bit is not set
+ */
+ bool isEccOverrideFlagSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_ECC_OVERRIDE) ? true : false);
+ }
+
+ /**
+ * @brief Determines if ECC required bit is set
+ *
+ * @return Returns True if ECC required flag is set
+ * False if ECC required flag is not set
+ */
+ bool isEccFlagSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_ECC_REQUIRED) ? true : false);
+ }
+
+ /**
+ * @brief Determines if Itag required bit is set
+ *
+ * @return Returns True if Itag required flag is set
+ * False if Itag required flag is not set
+ */
+ bool isItagFlagSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_ITAG) ? true : false);
+ }
+
+ /**
+ * @brief Determines if Cache Inhibited mode is set
+ *
+ * @return Returns True if Cache Inhibited Mode flag is set
+ * False if Cache Inhibited Mode flag is not set
+ */
+ bool isCacheInhibitModeFlagSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_CACHE_INHIBIT) ? true : false);
+ }
+
+ /**
+ * @brief Determines if PBA flag is set
+ *
+ * @return Returns True if PBA Flag is set
+ * False if PBA flag is not set
+ */
+ bool isPbaFlagSet()
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_TARGET_PBA) ? true : false);
+ }
+
+ /**
+ * @brief Determines if Auto Increment Mode is set
+ *
+ * @return Returns True if Auto Increment mode is set
+ * False if Auto Increment is not set
+ */
+ bool isAutoIncrModeSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_AUTO_INCR_ON) ? true : false);
+ }
+
+ /**
+ * @brief Determines if Fast Mode is set
+ *
+ * @return Returns True if Fast mode is set
+ * False if Fast mode is not set
+ */
+ uint32_t isFastModeSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_FAST_MODE_ON) ? true : false);
+ }
+
+ /**
+ * @brief Determines if LCO Mode is set
+ *
+ * @return Returns True if LCO mode is set
+ * False if LCO mode is not set
+ */
+ uint32_t isPbaLcoModeSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_LCO_ENABLED) ? true : false);
+ }
+
+ /**
+ * @brief Calculates Data length in alignment with PBA/ADU Cacheline
+ * (128B/8B respectively)
+ *
+ * @return Returns Data length in alignment with PBA/ADU Cacheline
+ */
+ uint64_t getDataLenCacheAlign() const
+ {
+ uint64_t l_len = (len / 8);
+ if(flags & SBE_MEM_ACCESS_FLAGS_TARGET_PBA)
+ {
+ l_len = (l_len / 16);
+ }
+ return l_len;
+ }
+
+}sbeMemAccessReqMsgHdr_t;
+
+/**
+ * @brief Structure for SBE OCC Get/Put Sram Access ChipOps (0xA403/A404)
+ */
+typedef struct
+{
+ uint32_t reserved:24; // Not used
+ sbeSramAccessMode mode:8; // Channel select 0-3
+ uint32_t addr; // 32-Bit Memory Address
+ uint32_t len; // Length of Data in Bytes
+}sbeOccSramAccessReqMsgHdr_t;
+
+// Maximum number of capabilities
+static const uint32_t SBE_MAX_CAPABILITIES = 18;
+
+/**
+ * @brief structure for SBE Get Capabilities chipop (0xA802) contents.
+ *
+ */
+typedef struct sbeCapabilityRespMsg
+{
+ uint32_t verMajor:16;
+ uint32_t verMinor:16;
+ uint32_t fwCommitId;
+ uint32_t capability[SBE_MAX_CAPABILITIES];
+ // ctor. constructor will initialise all values.
+ sbeCapabilityRespMsg();
+}sbeCapabilityRespMsg_t;
+
+// TODO via RTC 128658
+// We may be able to replace this structure by sbeRespGenHdr_t
+
+/**
+ * @brief Command response structure to hold the primary and secondary
+ * status values. This will be utilized when a command class
+ * validation or state machine check fails.
+ *
+ */
+typedef struct
+{
+ uint32_t prim_status:16 ; // Primary Response Status
+ uint32_t sec_status:16 ; // Secondary Response Status
+
+ /**
+ * @brief initialize the response status
+ **/
+ void init()
+ {
+ prim_status = SBE_PRI_OPERATION_SUCCESSFUL;
+ sec_status = SBE_SEC_OPERATION_SUCCESSFUL;
+ }
+
+ /**
+ * @brief set the primary and secondary status
+ *
+ * @param[in] i_prim Primary status
+ * @param[in] i_sec Secondary status
+ *
+ **/
+ void setStatus(const uint16_t i_prim, const uint16_t i_sec)
+ {
+ prim_status = i_prim;
+ sec_status = i_sec;
+ }
+} sbeCmdRespHdr_t;
+
+extern sbeCmdRespHdr_t g_sbeCmdRespHdr;
+
+/**
+ * @brief structure for Control Instruction Chipop (0xA701) contents.
+ *
+ */
+typedef struct
+{
+ uint32_t reserved:12;
+ sbeErrorMode mode:4;
+ sbeCoreChipletId coreChipletId:8;
+ sbeThreadNum threadNum:4;
+ sbeThreadOps threadOps:4;
+
+ /**
+ * @brief Validate input arguments
+ *
+ * @return bool, true if the validation is success, else false for
+ * validation failure
+ */
+ bool validateInputArgs()
+ {
+ bool l_validatePassFlag = true;
+ // Validate Thread Command / Thread Num / Error Mode
+ if((threadOps > THREAD_SRESET_INS) ||
+ (mode > IGNORE_HW_ERRORS) ||
+ !((threadNum <= SMT4_THREAD3) || (threadNum == SMT4_THREAD_ALL)))
+ {
+ SBE_ERROR(SBE_FUNC "Invalid Parameter by User, ThreadOps[%d] "
+ "mode[%d] ThreadNum[%d]", threadOps, mode, threadNum);
+ l_validatePassFlag = false;
+ }
+ return l_validatePassFlag;
+ }
+
+ /**
+ * @brief Process the input to find out core/thread ids to iterate
+ * over HWP for the internal business logic
+ *
+ * @param[out] o_core, Core Id to start with in the iteration
+ * @param[out] o_coreCntMax, Core Max count to iterate, start from o_core
+ * @param[out] o_threadCnt, Thread Num to start with in the iteration
+ * @param[out] o_threadCntMax, Thread Max Num to iterate, start from
+ * o_threadCnt
+ *
+ * @return void
+ */
+ void processInputDataToIterate(uint8_t & o_core, uint8_t & o_coreCntMax,
+ uint8_t & o_threadCnt, uint8_t & o_threadCntMax)
+ {
+ //Default Init
+ o_threadCnt = SMT4_THREAD0;
+ o_threadCntMax = SMT4_THREAD_MAX;
+
+ o_core = SMT4_CORE0_ID;
+ o_coreCntMax = SMT4_CORE_ID_MAX;
+
+ if( SMT4_ALL_CORES != coreChipletId )
+ {
+ o_core = coreChipletId;
+ o_coreCntMax = coreChipletId;
+ }
+ if( SMT4_THREAD_ALL != threadNum )
+ {
+ o_threadCnt = threadNum;
+ o_threadCntMax = threadNum;
+ }
+ }
+}sbeCntlInstRegMsgHdr_t;
+
+/**
+ * @brief Get Ring access message header
+ */
+typedef struct
+{
+ uint32_t ringAddr;
+ uint32_t ringLenInBits;
+ uint32_t reserved:16;
+ uint32_t ringMode:16;
+}sbeGetRingAccessMsgHdr_t;
+
+/**
+ * @brief Reg access message header
+ */
+typedef struct
+{
+ uint32_t reserved:8;
+ uint32_t coreChiplet:8;
+ uint32_t threadNr:4;
+ uint32_t regType:4;
+ uint32_t numRegs:8;
+
+ /**
+ * @brief checks if it is valid request.
+ *
+ * @return true if valid request, false otherwise
+ */
+ bool isValidRequest() const
+ {
+ return (( SBE_REG_ACCESS_FPR >= regType )
+ &&( SBE_MAX_REG_ACCESS_REGS >= numRegs )
+ &&( SMT4_THREAD3 >= threadNr )
+ &&( SMT4_CORE0_ID <= coreChiplet )
+ &&( SMT4_CORE_ID_MAX >= coreChiplet )) ? true:false;
+ }
+}sbeRegAccessMsgHdr_t;
+
+/**
+ * @brief reg scom package
+ */
+typedef struct
+{
+ uint32_t regNr;
+ uint32_t hiData;
+ uint32_t lowData;
+
+ /**
+ * @brief data for a register.
+ *
+ * @return data.
+ */
+ uint64_t getData() const
+ {
+ return (((uint64_t)hiData << 32 ) | lowData );
+ }
+}sbeRegAccessPackage_t;
+
+#endif // __SBEFW_SBESP_MSG_H
diff --git a/src/sbefw/sbeXipUtils.H b/src/sbefw/sbeXipUtils.H
new file mode 100644
index 00000000..b9ce992e
--- /dev/null
+++ b/src/sbefw/sbeXipUtils.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeXipUtils.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef SBE_XIP_UTILS_H
+#define SBE_XIP_UTILS_H
+
+#include "p9_xip_image.h"
+#include "ppe42_scom.h" // for PPE_STVD
+#include "sbe_link.H" // for SBE_BASE_ORIGIN, SBE_SEEPROM_BASE_ORIGIN
+
+// Unconditional jump to a memory location
+#define JUMP_TO_ADDR(VAL ) \
+{ \
+asm volatile ( \
+ "mtlr %0 \n\t" \
+ : \
+ : "r" (VAL)); \
+asm volatile ( \
+ "blr \n\t" \
+ : \
+ );\
+}
+
+// PIBMEM start address
+const uint32_t g_pibMemAddr = SBE_BASE_ORIGIN;
+// SEEPROM start address
+const uint32_t g_headerAddr = SBE_SEEPROM_BASE_ORIGIN;
+// IVPR register address
+const uint32_t g_ivprLoc = 0xC0000160;
+
+// Get XIP image header
+inline P9XipHeader * getXipHdr()
+{
+ P9XipHeader *hdr = (P9XipHeader *)( g_headerAddr );
+ return hdr;
+}
+
+// Get Section start addess
+inline uint8_t * getSectionAddr( P9XipSection * i_section )
+{
+ return ( (uint8_t *)( g_headerAddr + i_section->iv_offset));
+}
+#endif // SBE_XIP_UTILS_H
diff --git a/src/sbefw/sbe_host_intf.H b/src/sbefw/sbe_host_intf.H
new file mode 100644
index 00000000..24658f16
--- /dev/null
+++ b/src/sbefw/sbe_host_intf.H
@@ -0,0 +1,89 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbe_host_intf.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbe_host_intf.H
+ *
+ * @brief This file contains the Host-SBE interface protocol common details
+ */
+
+#ifndef __SBEFW_SBE_HOST_INTF_H
+#define __SBEFW_SBE_HOST_INTF_H
+
+#include <stdint.h>
+
+/**
+ * $Version: Conforms to HOST-SBE Interface Spec v0.5a
+ */
+
+/*
+ * Constants for SBE FW major and minor number
+ */
+static const uint16_t SBE_SBEFW_HOST_MAJOR_VERSION = 1;
+static const uint16_t SBE_SBEFW_HOST_MINOR_VERSION = 0;
+
+/**
+ * @brief enums for SBE-Host interface command class
+ */
+enum sbePsuCommandClass
+ {
+ SBE_PSU_CMD_CLASS_UNKNOWN = 0,
+ SBE_PSU_CMD_CLASS_CORE_STATE = 0xD1,
+ SBE_PSU_CMD_CLASS_RING_ACCESS = 0xD3,
+ };
+
+/**
+ * @brief enums for SBE-Host interface core state control commands
+ */
+enum sbePsuCoreStateControlCommands
+{
+ SBE_PSU_CMD_CONTROL_DEADMAN = 0x01,
+ SBE_PSU_CMD_UNKNOWN = 0xFF,
+};
+
+/**
+ * @brief enums for SBE-Host interface ring access messages
+ */
+enum sbePsuRingAccessMessages
+{
+ SBE_PSU_MSG_PUT_RING_FROM_IMAGE = 0x01,
+ SBE_PSU_MSG_UNKNOWN = 0xFF,
+};
+
+/**
+ * @brief enums denoting control flags
+ *
+ */
+enum sbePsuControlFlags
+{
+ SBE_PSU_FLAGS_RESP_REQUIRED = 0x0100,
+ SBE_PSU_FLAGS_ACK_REQUIRED = 0x0200,
+};
+
+enum sbePsuDmtCmdFlags
+{
+ SBE_PSU_FLAGS_START_DMT = 0x0001,
+ SBE_PSU_FLAGS_STOP_DMT = 0x0002,
+};
+
+#endif // __SBEFW_SBE_HOST_INTF_H
diff --git a/src/sbefw/sbe_sp_intf.H b/src/sbefw/sbe_sp_intf.H
new file mode 100644
index 00000000..0734343d
--- /dev/null
+++ b/src/sbefw/sbe_sp_intf.H
@@ -0,0 +1,408 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbe_sp_intf.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file sbe_sp_intf.H
+ *
+ * @brief This file contains the SP - SBE interface protocol common details
+ */
+
+#ifndef __SBEFW_SBE_SP_INTF_H
+#define __SBEFW_SBE_SP_INTF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * $Version: Conforms to SP-SBE Interface Spec v0.8e
+ */
+
+/*
+ * Constants for SBE FW major and minor number
+ */
+static const uint16_t SBE_FW_MAJOR_VERSION = 1;
+static const uint16_t SBE_FW_MINOR_VERSION = 1;
+
+/**
+ * @brief enums for SBE command classes
+ *
+*/
+enum sbeCommandClass
+{
+ SBE_CMD_CLASS_UNKNOWN = 0,
+ SBE_CMD_CLASS_IPL_CONTROL = 0xA1,
+ SBE_CMD_CLASS_SCOM_ACCESS = 0xA2,
+ SBE_CMD_CLASS_RING_ACCESS = 0xA3,
+ SBE_CMD_CLASS_MEMORY_ACCESS = 0xA4,
+ SBE_CMD_CLASS_REGISTER_ACCESS = 0xA5,
+ SBE_CMD_CLASS_ARRAY_ACCESS = 0xA6,
+ SBE_CMD_CLASS_INSTRUCTION_CONTROL = 0xA7,
+ SBE_CMD_CLASS_GENERIC_MESSAGE = 0xA8,
+ SBE_CMD_CLASS_MPIPL_COMMANDS = 0xA9,
+};
+
+/**
+ * @brief enums for SBE Istep Control command class
+ *
+*/
+enum sbeIplControlCommands
+{
+ SBE_CMD_EXECUTE_ISTEP = 0x01, /* Execute istep */
+ SBE_CMD_CONTINUE_BOOT = 0x02, /* Continue SBE Boot */
+};
+
+/**
+ * @brief enums for SCOM Access Messages
+ *
+*/
+enum sbeScomAccessCommands
+{
+ SBE_CMD_GETSCOM = 0x01, /* Get SCOM */
+ SBE_CMD_PUTSCOM = 0x02, /* Put SCOM */
+ SBE_CMD_MODIFYSCOM = 0x03, /* Modify SCOM */
+ SBE_CMD_PUTSCOM_MASK = 0x04, /* Put SCOM under mask */
+ SBE_CMD_MULTISCOM = 0x05, /* Execute Multi SCOM */
+};
+
+/**
+ * @brief enum for modify mode
+ *
+*/
+enum sbeChipOpModifyMode
+{
+ SBE_MODIFY_MODE_OR = 0x01,
+ SBE_MODIFY_MODE_AND = 0x02,
+ SBE_MODIFY_MODE_XOR = 0x03,
+};
+
+/**
+ * @brief enums for Ring Access Messages
+ *
+*/
+enum sbeRingAccessCommands
+{
+ SBE_CMD_GETRING = 0x01, /* Get Ring */
+ SBE_CMD_PUTRING = 0x02, /* Put Ring */
+};
+
+/**
+ * @brief enums for Memory Access Messages
+ *
+*/
+enum sbeMemoryAccesCommands
+{
+ SBE_CMD_GETMEM = 0x01, /* Get Memory (Proc/PBA) */
+ SBE_CMD_PUTMEM = 0x02, /* Put Memory (Proc/PBA) */
+ SBE_CMD_GETSRAM_OCC = 0x03, /* Get Memory (OCC SRAM) */
+ SBE_CMD_PUTSRAM_OCC = 0x04, /* Put Memory (OCC SRAM) */
+};
+
+/**
+ * @brief enums for GPR/SPR/FPR Access Messages
+ *
+*/
+enum sbeRegisterAccessCommands
+{
+ SBE_CMD_GETREG = 0x01, /* Get Register (GPR,SPR,FPR) */
+ SBE_CMD_PUTREG = 0x02, /* Put Register (GPR,SPR,FPR) */
+};
+
+/**
+ * @brief enums for Trace Array Access Messages
+ *
+*/
+enum sbeArrayAccessCommands
+{
+ SBE_CMD_GET_FAST_ARRAY = 0x01, /* Get Fast Array */
+ SBE_CMD_GET_TRACE_ARRAY = 0x02, /* Get Trace Array */
+ SBE_CMD_CONTROL_TRACE_ARRAY = 0x03, /* Control Trace Array */
+};
+
+/**
+ * @brief enums for Instruction Control Messages
+ *
+*/
+enum sbeInstructionControlCommands
+{
+ SBE_CMD_CONTROL_INSTRUCTIONS = 0x01, /* Control Instructions */
+};
+
+/**
+ * @brief enums for Generic Messages
+ *
+*/
+enum sbeGenericMessageCommands
+{
+ SBE_CMD_GET_SBE_FFDC = 0x01, /* Get FFDC */
+ SBE_CMD_GET_SBE_CAPABILITIES = 0x02, /* GET SBE capabilities */
+ SBE_CMD_GET_FREQ_SUPPORTED = 0x03, /* Get Supported frequencies */
+ SBE_CMD_ABORT = 0x05, /* Sbe Abort */
+};
+
+enum sbeMpIplCommands
+{
+ SBE_CMD_MPIPL_ENTER = 0x01, /* Enter MPIPL */
+ SBE_CMD_MPIPL_CONTINUE = 0x02, /* Continue MPIPL */
+};
+
+/**
+ * @brief enums for primary SBE response
+ *
+*/
+enum sbePrimResponse
+{
+ SBE_PRI_OPERATION_SUCCESSFUL = 0x00,
+ SBE_PRI_INVALID_COMMAND = 0x01,
+ SBE_PRI_INVALID_DATA = 0x02,
+ SBE_PRI_SEQUENCE_ERROR = 0x03,
+ SBE_PRI_INTERNAL_ERROR = 0x04,
+ SBE_PRI_GENERIC_EXECUTION_FAILURE = 0xFE,
+};
+
+/**
+ * @brief enums for secondary SBE response
+ * @TODO via RTC: 129763
+ * Discuss on SBE_SEC_INVALID_TARGET_ID_PASSED
+ *
+*/
+enum sbeSecondaryResponse
+{
+ SBE_SEC_OPERATION_SUCCESSFUL = 0x00,
+ SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED = 0x01,
+ SBE_SEC_COMMAND_NOT_SUPPORTED = 0x02,
+ SBE_SEC_INVALID_ADDRESS_PASSED = 0x03,
+ SBE_SEC_INVALID_TARGET_TYPE_PASSED = 0x04,
+ SBE_SEC_INVALID_TARGET_ID_PASSED = 0x05,
+ SBE_SEC_SPECIFIED_TARGET_NOT_PRESENT = 0x06,
+ SBE_SEC_SPECIFIED_TARGET_NOT_FUNCTIONAL = 0x07,
+ SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE = 0x08,
+ SBE_SEC_FUNCTIONALITY_NOT_SUPPORTED = 0x09,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION = 0x0A,
+ SBE_SEC_SECURITY_VALIDATION_FAILED = 0x0B,
+ SBE_SEC_OS_FAILURE = 0x0C,
+ SBE_SEC_FIFO_ACCESS_FAILURE = 0x0D,
+ SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA = 0x0E,
+ SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA = 0x0F,
+ SBE_SEC_HW_OP_TIMEOUT = 0x10,
+ SBE_SEC_PCB_PIB_ERR = 0x11,
+};
+
+/**
+ * @brief enums for SBE command timeout values
+ *
+*/
+enum sbeCmdRespTimeout
+{
+ SBE_CMD_TIMEOUT_SHORT_IN_MSEC = 100,
+ SBE_CMD_TIMEOUT_LONG_IN_MSEC = 30000,
+};
+
+/**
+ * @brief enums for PCB-PIB Generic Error codes
+ *
+*/
+enum sbePCBPIBErrorRC
+{
+ SBE_PCB_PIB_ERROR_NONE = 0x00,
+ SBE_PCB_PIB_ERROR_RESOURCE_OCCUPIED = 0x01,
+ SBE_PCB_PIB_ERROR_CHIPLET_OFFLINE = 0x02,
+ SBE_PCB_PIB_ERROR_PARTIAL_GOOD = 0x03,
+ SBE_PCB_PIB_ERROR_ADDRESS_ERROR = 0x04,
+ SBE_PCB_PIB_ERROR_CLOCK_ERROR = 0x05,
+ SBE_PCB_PIB_ERROR_PACKET_ERROR = 0x06,
+ SBE_PCB_PIB_ERROR_TIMEOUT = 0x07,
+};
+
+/**
+ * @brief capabilities index values.
+ * Get Capability response will return 18 capabilities. This
+ * enum tells the index for each capability. Currently each generic
+ * functionality( scom, IPL ) etc span across two capabilities.
+ */
+enum
+{
+ GENERIC_CAPABILTITY_START_IDX = 0,
+ IPL_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 2,
+ SCOM_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 4,
+ RING_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 6,
+ MEMORY_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 8,
+ REGISTER_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 10,
+ ARRAY_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 12,
+ INSTRUCTION_CTRL_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 14,
+ GENERIC_CHIPOP_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 16,
+};
+/**
+ * @brief capabilities enum values.
+ *
+ */
+enum
+{
+ HWP_FFDC_COLLECTION_SUPPPORTED = 0x00000001,
+ SBE_FFDC_COLLECTION_SUPPPORTED = 0x00000002,
+ ADDRESS_BLACKLISTING_SUPPPORTED = 0x00000004,
+ FIFO_RESET_SUPPPORTED = 0x00000008,
+ EXECUTE_ISTEP_SUPPPORTED = 0xA1000001,
+ IS_SBE_DONE_SUPPPORTED = 0xA1000002,
+ GET_SCOM_SUPPPORTED = 0xA2000001,
+ PUT_SCOM_SUPPPORTED = 0xA2000002,
+ MODIFY_SCOM_SUPPPORTED = 0xA2000004,
+ PUT_SCOM_UNDER_MASK_SUPPPORTED = 0xA2000008,
+ MULTI_SCOM_SUPPPORTED = 0xA2000010,
+ GET_RING_SUPPPORTED = 0xA3000001,
+ PUT_RING_SUPPPORTED = 0xA3000002,
+ GET_MEMORY_SUPPPORTED = 0xA4000001,
+ PUT_MEMORY_SUPPPORTED = 0xA4000002,
+ GET_SRAM_OCC_SUPPPORTED = 0xA4000004,
+ PUT_SRAM_OCC_SUPPPORTED = 0xA4000008,
+ GET_SRAM_CME_SUPPPORTED = 0xA4000010,
+ PUT_SRAM_CME_SUPPPORTED = 0xA4000011,
+ GET_REGISTER_SUPPPORTED = 0xA5000001,
+ PUT_REGISTER_SUPPPORTED = 0xA5000002,
+ READ_FAST_ARRAY_SUPPPORTED = 0xA6000001,
+ READ_TRACE_ARRAY_SUPPPORTED = 0xA6000002,
+ COLLECT_TRACE_ARRAY_SUPPPORTED = 0xA6000004,
+ CONTROL_INSTRUCTIONS_SUPPPORTED = 0xA7000001,
+ GET_SBE_FFDC_SUPPPORTED = 0xA8000001,
+ GET_SBE_CAPABILITIES_SUPPPORTED = 0xA8000002,
+ GET_SBE_FREQUENCIES_SUPPPORTED = 0xA8000004,
+ GET_SBE_STATE_SUPPPORTED = 0xA8000008,
+};
+
+/**
+ * * @brief enums for SBE Memory Access command flags
+ *
+ */
+enum sbeMemoryAccessFlags
+{
+ SBE_MEM_ACCESS_FLAGS_TARGET_PROC = 0x0001, //required in ADU
+ SBE_MEM_ACCESS_FLAGS_TARGET_PBA = 0x0002, //required in PBA
+ SBE_MEM_ACCESS_FLAGS_AUTO_INCR_ON = 0x0004,
+ SBE_MEM_ACCESS_FLAGS_ECC_REQUIRED = 0x0008, //required only in ADU-GET
+ SBE_MEM_ACCESS_FLAGS_ECC_OVERRIDE = 0x0008, //required only in ADU-PUT
+ SBE_MEM_ACCESS_FLAGS_ITAG = 0x0010, //ITAG Mode in ADU
+ SBE_MEM_ACCESS_FLAGS_FAST_MODE_ON = 0x0020,
+ SBE_MEM_ACCESS_FLAGS_LCO_ENABLED = 0x0040, //required only in PBA-PUT
+ SBE_MEM_ACCESS_FLAGS_CACHE_INHIBIT = 0x0080, //required in I/O oper ADU
+};
+
+/**
+ * @brief enum for various modes for Sram Access
+ */
+enum sbeSramAccessMode
+{
+ NORMAL_MODE = 0x1,
+ DEBUG_MODE = 0x2,
+ CIRCULAR_MODE = 0x3,
+};
+/*
+ * Constants for maximum number of register supported in reg access chipop.
+ */
+static const uint32_t SBE_MAX_REG_ACCESS_REGS = 64;
+
+/**
+ * @brief Error Mode enum
+ */
+enum sbeErrorMode
+{
+ EXIT_ON_FIRST_ERROR = 0x0, // Bail out on first error
+ IGNORE_HW_ERRORS = 0x01, // Attempt best case
+};
+
+/**
+ * @brief Core Chiplet Id Enum
+ */
+enum sbeCoreChipletId
+{
+ SMT4_CORE0_ID = 0x20,
+ SMT4_CORE_ID_MAX = 0x38,
+ SMT4_ALL_CORES = 0xFF,
+};
+
+/**
+ * @brief Thread Num Enum
+ */
+enum sbeThreadNum
+{
+ SMT4_THREAD0 = 0x0,
+ SMT4_THREAD1 = 0x1,
+ SMT4_THREAD2 = 0x2,
+ SMT4_THREAD3 = 0x3,
+ SMT4_THREAD_MAX = 0x4,
+ SMT4_THREAD_ALL = 0xF,
+};
+
+/**
+ * @brief Thread Operation Enum
+ */
+enum sbeThreadOps
+{
+ THREAD_START_INS = 0x0,
+ THREAD_STOP_INS = 0x1,
+ THREAD_STEP_INS = 0x2,
+ THREAD_SRESET_INS = 0x3,
+};
+
+/**
+ * @brief enums for Reg access register type
+ *
+ */
+enum sbeRegAccesRegType
+{
+ SBE_REG_ACCESS_GPR = 0x00,
+ SBE_REG_ACCESS_SPR = 0x01,
+ SBE_REG_ACCESS_FPR = 0x02,
+};
+
+/*
+ * @brief enums for target types used in ring access chip op
+*/
+typedef enum
+{
+ TARGET_PROC_CHIP = 0x0000,
+ TARGET_EX = 0x0001,
+ TARGET_PERV = 0x0002,
+ TARGET_MCS = 0x0003,
+} sbeRingTargetTypes_t;
+
+/*
+ * @brief enums for access modes used in ring access chip op
+ */
+typedef enum
+{
+ SBE_RING_MODE_NO_HEADER_CHECK = 0x0001, ///< Don't check header
+ SBE_RING_MODE_SET_PULSE_NO_OPCG_COND = 0x0002, ///< Set pulse with
+ /// no OPCG conditioning
+ SBE_RING_MODE_SET_PULSE_NSL = 0x0004, ///< Set pulse with NSL
+ /// pulse
+ SBE_RING_MODE_SET_PULSE_SL = 0x0008, ///< Set pulse with SL
+ /// pulse
+ SBE_RING_MODE_SET_PULSE_ALL = 0x0010, ///< Set pulse with pulse
+ /// to all hold types
+} sbeRingAccessModes_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SBEFW_SBE_SP_INTF_H */
diff --git a/src/sbefw/sbecmdcntlinst.C b/src/sbefw/sbecmdcntlinst.C
new file mode 100644
index 00000000..faed1e5b
--- /dev/null
+++ b/src/sbefw/sbecmdcntlinst.C
@@ -0,0 +1,203 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdcntlinst.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdcntlinst.C
+ *
+ * @brief This file contains the SBE Control Instruction chipOps
+ *
+ */
+
+#include "sbecmdcntlinst.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbeFifoMsgUtils.H"
+
+#include "fapi2.H"
+#include "p9_thread_control.H"
+
+using namespace fapi2;
+
+// This is used to find out the array index in g_control_reg_map in
+// p9_thread_control.C
+static const uint8_t SINGLE_THREAD_BIT_MASK = 0x08;
+// TODO via RTC 152424
+// Currently all proecdures in core directory are in seeprom.
+// So we have to use function pointer to force a long call.
+p9_thread_control_FP_t threadCntlhwp = &p9_thread_control;
+
+/* @brief Map User Thread Command to Hwp ThreadCommands Enum */
+ThreadCommands getThreadCommand(const sbeCntlInstRegMsgHdr_t & i_req)
+{
+ ThreadCommands l_cmd = PTC_CMD_START;
+ switch(i_req.threadOps)
+ {
+ case THREAD_START_INS: l_cmd = PTC_CMD_START; break;
+ case THREAD_STOP_INS: l_cmd = PTC_CMD_STOP; break;
+ case THREAD_STEP_INS: l_cmd = PTC_CMD_STEP; break;
+ case THREAD_SRESET_INS: l_cmd = PTC_CMD_SRESET; break;
+ }
+ return l_cmd;
+}
+
+/* @brief Map User Mode Command to Hwp Warn Check flag */
+inline bool getWarnCheckFlag(const sbeCntlInstRegMsgHdr_t & i_req)
+{
+ bool l_warnCheck = false;
+ if( EXIT_ON_FIRST_ERROR != i_req.mode )
+ {
+ l_warnCheck = true;
+ }
+ return l_warnCheck;
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeCntlInst Sbe control instructions function
+//
+// @return RC from the underlying FIFO utility
+///////////////////////////////////////////////////////////////////////
+uint32_t sbeCntlInst(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeCntlInst "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ ReturnCode l_fapiRc = FAPI2_RC_SUCCESS;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+ sbeResponseFfdc_t l_ffdc;
+
+ // Create the req struct for Control Instructions Chip-op
+ sbeCntlInstRegMsgHdr_t l_req = {0};
+
+ do
+ {
+ // Get the Req Struct Data sbeCntlInstRegMsgHdr_t from upstream Fifo
+ uint32_t l_len2dequeue = sizeof(l_req) / sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, (uint32_t *)&l_req, true);
+
+ // If FIFO failure
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ SBE_INFO("mode[0x%04X] coreChipletId[0x%08X] threadNum[0x%04X] "
+ "threadOps[0x%04X] ", l_req.mode, l_req.coreChipletId,
+ l_req.threadNum, l_req.threadOps);
+
+ // Validate Input Args
+ if( false == l_req.validateInputArgs())
+ {
+ SBE_ERROR(SBE_FUNC "ValidateAndMapInputArgs failed");
+ l_respHdr.setStatus( SBE_PRI_INVALID_DATA,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION );
+ break;
+ }
+
+ // Fetch HWP mapped values
+ bool l_warnCheck = getWarnCheckFlag(l_req);
+ ThreadCommands l_cmd = getThreadCommand(l_req);
+
+ // Default assignment not required since it is assigned below
+ uint8_t l_core, l_coreCntMax;
+ uint8_t l_threadCnt, l_threadCntMax;
+
+ l_req.processInputDataToIterate(l_core, l_coreCntMax,
+ l_threadCnt, l_threadCntMax);
+ fapi2::buffer<uint64_t> l_data64;
+ uint64_t l_state;
+ do
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_CORE>
+ l_coreTgt(plat_getTargetHandleByChipletNumber
+ <fapi2::TARGET_TYPE_CORE>(l_core));
+ if(!l_coreTgt.isFunctional())
+ {
+ continue;
+ }
+
+ uint8_t l_thread = l_threadCnt;
+ do
+ {
+ // Call the Procedure
+ l_fapiRc = threadCntlhwp(
+ l_coreTgt,
+ (SINGLE_THREAD_BIT_MASK >> l_thread),
+ l_cmd, l_warnCheck,
+ l_data64, l_state);
+
+ if(l_fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "Failed for Core[%d] Thread [%d] "
+ "Cmd[%d] Mode[%d]", l_core, l_thread, l_req.threadOps,
+ l_req.mode);
+ if(IGNORE_HW_ERRORS == l_req.mode)
+ {
+ // No need to delete the l_fapiRc handle,it will get
+ // over-written
+ SBE_INFO(SBE_FUNC "Continuing in case of HW Errors"
+ " As user has passed to ignore errors.");
+ continue;
+ }
+ else
+ {
+ SBE_ERROR(SBE_FUNC "Breaking out, since User has "
+ "Selected the mode to exit on first error.");
+ l_respHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+ }
+ }while(++l_thread < l_threadCntMax);
+
+ // If FapiRc from the inner loop (thread loop), just break here
+ if ( l_fapiRc )
+ {
+ break; // From core while loop
+ }
+ }while(++l_core < l_coreCntMax);
+
+ }while(0);
+
+ // Create the Response to caller
+ do
+ {
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ break;
+ }
+
+ l_rc = sbeDsSendRespHdr(l_respHdr, l_ffdc);
+ }while(0);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
diff --git a/src/sbefw/sbecmdcntlinst.H b/src/sbefw/sbecmdcntlinst.H
new file mode 100644
index 00000000..39e84135
--- /dev/null
+++ b/src/sbefw/sbecmdcntlinst.H
@@ -0,0 +1,45 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdcntlinst.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdcntlinst.H
+ *
+ * @brief This file contains the Interfaces for Control Instructions chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDCNTLINST_H
+#define __SBEFW_SBECMDCNTLINST_H
+
+#include <stdint.h>
+
+/**
+ * @brief sbeCntlInst : Implements SBE Control instructions ChipOp
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeCntlInst (uint8_t *i_pArg);
+
+#endif /* __SBEFW_SBECMDCNTLINST_H */
diff --git a/src/sbefw/sbecmdcntrldmt.C b/src/sbefw/sbecmdcntrldmt.C
new file mode 100644
index 00000000..a4cf8c97
--- /dev/null
+++ b/src/sbefw/sbecmdcntrldmt.C
@@ -0,0 +1,302 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdcntrldmt.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: sbe/sbefw/sbecmdcntrldmt.C
+ *
+ * @brief This file contains the Core State Control Messages
+ *
+ */
+
+#include "sbecmdcntrldmt.H"
+#include "sbetrace.H"
+#include "sbe_build_info.H"
+#include "sbeHostMsg.H"
+#include "sbeHostUtils.H"
+#include "sberegaccess.H"
+#include "sbestates.H"
+#include "sbe_sp_intf.H"
+#include "fapi2.H"
+#include "p9_sbe_check_master_stop15.H"
+#include "p9_perv_scom_addresses.H"
+#include "p9_block_wakeup_intr.H"
+
+using namespace fapi2;
+
+// Using Function pointer to force long call
+p9_sbe_check_master_stop15_FP_t p9_sbe_check_master_stop15_hwp =
+ &p9_sbe_check_master_stop15;
+
+////////////////////////////////////////////////////////////////////
+//Static initialization of the Dmt Pk timer
+PkTimer g_sbe_pk_dmt_timer;
+// Global Flag to indicate Dmt Timer Expiry
+bool g_SbeDmtTimerExpired = false;
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+void sbeDmtPkExpiryCallback(void *)
+{
+ #define SBE_FUNC "sbeDmtPkExpiryCallback"
+ SBE_INFO(SBE_FUNC" DMT Callback Timer has expired..Checkstop the system ");
+ g_SbeDmtTimerExpired = true;
+
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_DUMP_FAILURE_EVENT);
+
+ // check stop the system
+ uint32_t l_status = SBE_PCB_PIB_ERROR_NONE;
+ l_status = putscom_abs (PERV_N3_LOCAL_FIR_OR, N3_FIR_CORE_CHECKSTOP_BIT);
+ if(SBE_PCB_PIB_ERROR_NONE != l_status)
+ {
+ // Scom failed
+ SBE_ERROR(SBE_FUNC "PutScom failed for REG PERV_N3_LOCAL_FIR");
+ // TODO - Store the response in Async Response
+ // RTC:149074
+ }
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+uint32_t sbeStartCntlDmt()
+{
+ #define SBE_FUNC "sbeStartCntlDmt"
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ int l_pkRc = 0;
+ ReturnCode l_fapiRc = FAPI2_RC_SUCCESS;
+ g_SbeDmtTimerExpired = false;
+
+ do
+ {
+ // Fetch the Timer Value and Start a Pk Timer
+ uint64_t l_timerVal = 0;
+ l_rc = sbeReadPsu2SbeMbxReg(SBE_HOST_PSU_MBOX_REG1,
+ (sizeof(l_timerVal)/sizeof(uint64_t)),
+ &l_timerVal);
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC" Failed to extract SBE_HOST_PSU_MBOX_REG1");
+ break;
+ }
+
+ // Attach Callback
+ PkTimerCallback l_callback = &sbeDmtPkExpiryCallback;
+
+ // Create Timer with the above value
+ l_pkRc = pk_timer_create(&g_sbe_pk_dmt_timer, l_callback, NULL);
+ if(l_pkRc)
+ {
+ SBE_ERROR(SBE_FUNC" Pk Timer Create failed, RC=[%d]", l_pkRc);
+ l_rc = SBE_SEC_OS_FAILURE;
+ break;
+ }
+
+ // Schedule the timer
+ l_pkRc = pk_timer_schedule(&g_sbe_pk_dmt_timer,
+ PK_MILLISECONDS((uint32_t)l_timerVal));
+ if(l_pkRc)
+ {
+ SBE_ERROR(SBE_FUNC" Pk Timer Schedule failed, RC=[%d]", l_pkRc);
+ l_rc = SBE_SEC_OS_FAILURE;
+ break;
+ }
+
+ l_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4,
+ (uint64_t*)(&g_sbeSbe2PsuRespHdr),
+ (sizeof(g_sbeSbe2PsuRespHdr)/sizeof(uint64_t)),
+ true);
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC" Failed to write to "
+ "SBE_HOST_PSU_MBOX_REG4");
+ break;
+ }
+ // Set DMT State
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_DMT_ENTER_EVENT);
+
+ // Fetch the master core
+ Target<TARGET_TYPE_PROC_CHIP > l_procTgt = plat_getChipTarget();
+
+ // Fetch the MASTER_CORE attribute
+ uint8_t l_coreId = 0;
+ FAPI_ATTR_GET(fapi2::ATTR_MASTER_CORE,l_procTgt,l_coreId);
+
+ // Construct the Master Core Target
+ fapi2::Target<fapi2::TARGET_TYPE_CORE > l_coreTgt(
+ (uint64_t)l_coreId);
+
+ // Call Hwp p9_sbe_check_master_stop15 and loop
+ // Go around a loop till you get FAPI2_RC_SUCCESS
+ do
+ {
+ l_fapiRc = p9_sbe_check_master_stop15_hwp(l_coreTgt);
+ //Conversion is required here, since ReturnCode doesn't support
+ //comparision '!=' or '=='
+ //TODO RTC:149021
+ uint32_t l_rcFapi = l_fapiRc;
+ if( (l_rcFapi != fapi2::RC_CHECK_MASTER_STOP15_PENDING) &&
+ (l_rcFapi != FAPI2_RC_SUCCESS))
+ {
+ SBE_ERROR(SBE_FUNC" p9_sbe_check_master_stop15 "
+ "returned failure");
+ // Async Response to be stored
+ // RTC:149074
+ break;
+ }
+
+ // Only for Pending and Success case
+ if(RC_CHECK_MASTER_STOP15_PENDING != l_rcFapi) // Success
+ {
+ l_fapiRc = p9_block_wakeup_intr(l_coreTgt,
+ p9pmblockwkup::CLEAR );
+ if( l_fapiRc )
+ {
+ SBE_ERROR(SBE_FUNC" p9_block_wakeup_intr failed ");
+ // TODO via RTC 149074
+ // Async Response to be stored.
+ // Also checkstop the system.
+ break;
+ }
+ // indicate the Host via Bit SBE_SBE2PSU_DOORBELL_SET_BIT2
+ // that Stop15 exit
+ l_rc = sbeSetSbe2PsuDbBitX(SBE_SBE2PSU_DOORBELL_SET_BIT2);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC " Failed to Write "
+ "SBE_SBE2PSU_DOORBELL_SET_BIT2");
+ }
+ break; // Breakout from do..while()
+ }
+ // Stop 15 Pending Case
+ pk_sleep(PK_MILLISECONDS(SBE_DMT_SLEEP_INTERVAL));
+
+ }while(false == g_SbeDmtTimerExpired); // Inner Loop
+
+ }while(0); // Outer loop
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+uint32_t sbeStopCntlDmt()
+{
+ #define SBE_FUNC "sbeStopCntlDmt"
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ int l_pkRc = 0;
+
+ do
+ {
+ // Stop the Pk Timer - There is no call to check if the timer is
+ // still alive, if i call cancel on already expired timer, it
+ // returns error code.
+ if(false == g_SbeDmtTimerExpired)
+ {
+ SBE_INFO(SBE_FUNC " DmTimer hasn't expired yet.. stop it");
+ l_pkRc = pk_timer_cancel(&g_sbe_pk_dmt_timer);
+ if(l_pkRc)
+ {
+ // Check again if the failure is because of the timer already
+ // expired, in that case don't need to send any error response
+ // to hostboot
+ if(false == g_SbeDmtTimerExpired)
+ {
+ SBE_ERROR(SBE_FUNC " Pk Timer Cancel failed, RC=[%d]",
+ l_pkRc);
+ l_rc = SBE_SEC_OS_FAILURE;
+ }
+ break;
+ }
+ }
+
+ l_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4,
+ (uint64_t*)(&g_sbeSbe2PsuRespHdr),
+ (sizeof(g_sbeSbe2PsuRespHdr)/sizeof(uint64_t)),
+ true);
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC" Failed to write to SBE_HOST_PSU_MBOX_REG4");
+ break;
+ }
+ // Set Runtime State
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_DMT_COMP_EVENT);
+ }while(0);
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+uint32_t sbeControlDeadmanTimer (uint8_t *i_pArg)
+{
+ #define SBE_FUNC "sbeControlDeadmanTimer"
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ do
+ {
+ // Send Ack to Host via SBE_SBE2PSU_DOORBELL_SET_BIT1
+ // This util method will check internally on the mbox0 register if ACK
+ // is requested.
+ l_rc = sbeAcknowledgeHost();
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC " Failed to Sent Ack to Host over "
+ "SBE_SBE2PSU_DOORBELL_SET_BIT1");
+ break;
+ }
+
+ if(g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_START_DMT)
+ {
+ l_rc = sbeStartCntlDmt();
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC " Failed sbeStartCntlDmt");
+ break;
+ }
+ }
+ else if(g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_STOP_DMT)
+ {
+ l_rc = sbeStopCntlDmt();
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC " Failed sbeStopCntlDmt");
+ break;
+ }
+ }
+ else
+ {
+ SBE_ERROR(SBE_FUNC" Not a valid command ");
+ l_rc = SBE_SEC_COMMAND_NOT_SUPPORTED;
+ }
+ }while(0); // End of do-while
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
diff --git a/src/sbefw/sbecmdcntrldmt.H b/src/sbefw/sbecmdcntrldmt.H
new file mode 100644
index 00000000..4f133947
--- /dev/null
+++ b/src/sbefw/sbecmdcntrldmt.H
@@ -0,0 +1,59 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdcntrldmt.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdcntrldmt.H
+ *
+ * @brief This file contains the Core State Control Messages API header
+ *
+ */
+
+#ifndef __SBEFW_SBECMDCNTRLDMT_H
+#define __SBEFW_SBECMDCNTRLDMT_H
+
+#include <stdint.h>
+
+// Define for the Sleep interval between continuous HWP calls
+// for DMT functionality in Millisecond
+static const uint8_t SBE_DMT_SLEEP_INTERVAL = 1;
+
+// Bit-32 used to checkstop the system
+static const uint64_t N3_FIR_CORE_CHECKSTOP_BIT = 32;
+
+/**
+ * @brief Callback for Timer Expiry for DMT
+ *
+ * @return void
+ */
+void sbeDmtPkExpiryCallback(void *arg);
+
+/**
+ * @brief Control Deadman Timer command (0xD101)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return RC from the PSU access utility
+ */
+uint32_t sbeControlDeadmanTimer(uint8_t *i_pArg);
+
+#endif // __SBEFW_SBECMDCNTRLDMT_H
diff --git a/src/sbefw/sbecmdgeneric.C b/src/sbefw/sbecmdgeneric.C
new file mode 100644
index 00000000..e883993a
--- /dev/null
+++ b/src/sbefw/sbecmdgeneric.C
@@ -0,0 +1,118 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdgeneric.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdgeneric.C
+ *
+ * @brief This file contains the SBE generic Commands
+ *
+ */
+
+#include "sbecmdgeneric.H"
+#include "sbefifo.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbe_build_info.H"
+#include "sbeFifoMsgUtils.H"
+
+// Forward declaration
+sbeCapabilityRespMsg::sbeCapabilityRespMsg()
+{
+ verMajor= SBE_FW_MAJOR_VERSION;
+ verMinor = SBE_FW_MINOR_VERSION;
+ fwCommitId = SBE_COMMIT_ID;
+ // We can remove this for llop once all capabilities
+ // are supported
+ for(uint32_t idx = 0; idx < SBE_MAX_CAPABILITIES; idx++ )
+ {
+ capability[idx] = 0;
+ }
+ capability[IPL_CAPABILITY_START_IDX] =
+ EXECUTE_ISTEP_SUPPPORTED;
+
+ capability[SCOM_CAPABILITY_START_IDX] =
+ GET_SCOM_SUPPPORTED |
+ PUT_SCOM_SUPPPORTED |
+ MODIFY_SCOM_SUPPPORTED |
+ PUT_SCOM_UNDER_MASK_SUPPPORTED ;
+
+ capability[GENERIC_CHIPOP_CAPABILITY_START_IDX] =
+ GET_SBE_CAPABILITIES_SUPPPORTED;
+
+ capability[MEMORY_CAPABILITY_START_IDX] =
+ GET_MEMORY_SUPPPORTED |
+ PUT_MEMORY_SUPPPORTED |
+ GET_SRAM_OCC_SUPPPORTED |
+ PUT_SRAM_OCC_SUPPPORTED;
+
+ capability[INSTRUCTION_CTRL_CAPABILITY_START_IDX] =
+ CONTROL_INSTRUCTIONS_SUPPPORTED;
+ capability[REGISTER_CAPABILITY_START_IDX] =
+ GET_REGISTER_SUPPPORTED |
+ PUT_REGISTER_SUPPPORTED ;
+
+ capability[RING_CAPABILITY_START_IDX] =
+ GET_RING_SUPPPORTED;
+}
+// Functions
+//----------------------------------------------------------------------------
+uint32_t sbeGetCapabilities (uint8_t *i_pArg)
+{
+ #define SBE_FUNC "sbeGetCapabilities "
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t len = 0;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeCapabilityRespMsg_t capMsg;
+ sbeResponseFfdc_t l_ffdc;
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ rc = sbeUpFifoDeq_mult (len, NULL);
+ // @TODO via RTC : 130575
+ // Optimize both the RC handling and
+ // FIFO operation infrastructure.
+ if ( rc != SBE_SEC_OPERATION_SUCCESSFUL )
+ {
+ // Let command processor routine to handle the RC
+ break;
+ }
+
+ len = sizeof(capMsg)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &capMsg);
+ if (rc)
+ {
+ break;
+ }
+
+ rc = sbeDsSendRespHdr(respHdr, l_ffdc);
+ }while(0);
+
+ if( rc )
+ {
+ SBE_ERROR( SBE_FUNC"Failed. rc[0x%X]", rc);
+ }
+ return rc;
+ #undef SBE_FUNC
+}
diff --git a/src/sbefw/sbecmdgeneric.H b/src/sbefw/sbecmdgeneric.H
new file mode 100644
index 00000000..3fa174ad
--- /dev/null
+++ b/src/sbefw/sbecmdgeneric.H
@@ -0,0 +1,46 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdgeneric.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdgeneric.H
+ *
+ * @brief This file contains the SBE Generic command details
+ *
+ */
+
+#ifndef __SBEFW_SBECMDGENERIC_H
+#define __SBEFW_SBECMDGENERIC_H
+
+#include <stdint.h>
+
+
+/**
+ * @brief SBE Generic capabilities (0xA802)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetCapabilities(uint8_t *i_pArg);
+
+#endif // __SBEFW_SBECMDGENERIC_H
diff --git a/src/sbefw/sbecmdiplcontrol.C b/src/sbefw/sbecmdiplcontrol.C
new file mode 100644
index 00000000..0819a864
--- /dev/null
+++ b/src/sbefw/sbecmdiplcontrol.C
@@ -0,0 +1,830 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdiplcontrol.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdiplcontrol.C
+ *
+ * @brief This file contains the SBE istep chipOps
+ *
+ */
+
+#include "sbecmdiplcontrol.H"
+#include "sbefifo.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeFifoMsgUtils.H"
+#include "assert.h"
+#include "sberegaccess.H"
+#include "sbestates.H"
+
+#include "fapi2.H"
+// Pervasive HWP Header Files ( istep 2)
+#include <p9_sbe_attr_setup.H>
+#include <p9_sbe_tp_chiplet_init1.H>
+#include <p9_sbe_tp_gptr_time_initf.H>
+#include <p9_sbe_npll_initf.H>
+#include <p9_sbe_npll_setup.H>
+#include <p9_sbe_tp_switch_gears.H>
+#include <p9_sbe_clock_test2.H>
+#include <p9_sbe_tp_chiplet_reset.H>
+#include <p9_sbe_tp_repr_initf.H>
+#include <p9_sbe_tp_chiplet_init2.H>
+#include <p9_sbe_tp_arrayinit.H>
+#include <p9_sbe_tp_initf.H>
+#include <p9_sbe_tp_chiplet_init3.H>
+
+// Pervasive HWP Header Files ( istep 3)
+#include <p9_sbe_chiplet_reset.H>
+#include <p9_sbe_gptr_time_initf.H>
+#include <p9_sbe_chiplet_init.H>
+#include <p9_sbe_chiplet_pll_initf.H>
+#include <p9_sbe_chiplet_pll_setup.H>
+#include <p9_sbe_repr_initf.H>
+#include <p9_sbe_arrayinit.H>
+#include <p9_sbe_tp_enable_ridi.H>
+#include <p9_sbe_setup_boot_freq.H>
+#include <p9_sbe_nest_initf.H>
+#include <p9_sbe_nest_startclocks.H>
+#include <p9_sbe_io_initf.H>
+#include <p9_sbe_nest_enable_ridi.H>
+#include <p9_sbe_startclock_chiplets.H>
+#include <p9_sbe_scominit.H>
+#include <p9_sbe_lpc_init.H>
+#include <p9_sbe_fabricinit.H>
+#include <p9_sbe_mcs_setup.H>
+#include <p9_sbe_select_ex.H>
+// Cache HWP header file
+#include <p9_hcd_cache.H>
+#include <p9_hcd_cache_dcc_skewadjust_setup.H>
+#include <p9_hcd_cache_chiplet_l3_dcc_setup.H>
+#include <p9_hcd_cache_dpll_initf.H>
+// Core HWP header file
+#include <p9_hcd_core.H>
+
+// istep 5 hwp header files
+#include "p9_sbe_instruct_start.H"
+#include "p9_sbe_load_bootloader.H"
+
+#include "sbeXipUtils.H" // For getting hbbl offset
+// Forward declaration
+using namespace fapi2;
+ReturnCode sbeExecuteIstep (uint8_t i_major, uint8_t i_minor);
+bool validateIstep (uint8_t i_major, uint8_t i_minor);
+
+//typedefs
+typedef ReturnCode (*sbeIstepHwpProc_t)
+ (const Target<TARGET_TYPE_PROC_CHIP> & i_target);
+
+typedef ReturnCode (*sbeIstepHwpEq_t)
+ (const Target<TARGET_TYPE_EQ> & i_target);
+
+typedef ReturnCode (*sbeIstepHwpCore_t)
+ (const Target<TARGET_TYPE_CORE> & i_target);
+
+typedef union
+{
+ sbeIstepHwpProc_t procHwp;
+ sbeIstepHwpEq_t eqHwp;
+ sbeIstepHwpCore_t coreHwp;
+}sbeIstepHwp_t;
+// Wrapper function for HWP IPl functions
+typedef ReturnCode (*sbeIstep_t)( sbeIstepHwp_t );
+
+// Wrapper function which will call HWP.
+ReturnCode istepWithProc( sbeIstepHwp_t i_hwp );
+ReturnCode istepAttrSetup( sbeIstepHwp_t i_hwp );
+ReturnCode istepNoOp( sbeIstepHwp_t i_hwp );
+ReturnCode istepWithEq( sbeIstepHwp_t i_hwp);
+ReturnCode istepWithCore( sbeIstepHwp_t i_hwp);
+ReturnCode istepSelectEx( sbeIstepHwp_t i_hwp);
+ReturnCode istepLoadBootLoader( sbeIstepHwp_t i_hwp);
+ReturnCode istepCheckSbeMaster( sbeIstepHwp_t i_hwp);
+ReturnCode istepStartInstruction( sbeIstepHwp_t i_hwp);
+ReturnCode istepWithCoreConditional( sbeIstepHwp_t i_hwp);
+ReturnCode istepWithEqConditional( sbeIstepHwp_t i_hwp);
+
+// Using function pointer to force long call.
+p9_sbe_select_ex_FP_t p9_sbe_select_ex_hwp = &p9_sbe_select_ex;
+
+//structure for mapping SBE wrapper and HWP functions
+typedef struct
+{
+ sbeIstep_t istepWrapper;
+ sbeIstepHwp_t istepHwp;
+}istepMap_t;
+
+// Major isteps which are supported
+typedef enum
+{
+ SBE_ISTEP2 = 2,
+ SBE_ISTEP_FIRST = SBE_ISTEP2,
+ SBE_ISTEP3 = 3,
+ SBE_ISTEP_LAST_SLAVE = SBE_ISTEP3,
+ SBE_ISTEP4 = 4,
+ SBE_ISTEP5 = 5,
+ SBE_ISTEP_LAST_MASTER = SBE_ISTEP5,
+}sbe_supported_steps_t;
+
+// constants
+const uint32_t ISTEP2_MAX_SUBSTEPS = 17;
+const uint32_t ISTEP3_MAX_SUBSTEPS = 22;
+const uint32_t ISTEP4_MAX_SUBSTEPS = 34;
+const uint32_t ISTEP5_MAX_SUBSTEPS = 2;
+static const uint8_t ISTEP_MINOR_START = 1;
+static const uint8_t SLAVE_LAST_MINOR_ISTEP = 20;
+static const uint8_t ISTEP2_MINOR_START = 2;
+static const uint32_t SBE_ROLE_MASK = 0x00000002;
+
+// Globals
+// TODO: via RTC 123602 This global needs to move to a class that will store the
+// SBE FFDC.
+fapi2::ReturnCode g_iplFailRc = FAPI2_RC_SUCCESS;
+
+sbeRole g_sbeRole = SBE_ROLE_MASTER;
+
+// File static data
+
+static istepMap_t g_istep2PtrTbl[ ISTEP2_MAX_SUBSTEPS ] =
+ {
+ { NULL, NULL },
+ { &istepAttrSetup, { .procHwp = &p9_sbe_attr_setup }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_chiplet_init1 }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_gptr_time_initf }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_npll_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_npll_setup }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_switch_gears }},
+ { &istepWithProc, { .procHwp = &p9_sbe_clock_test2 }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_chiplet_reset }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_repr_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_chiplet_init2 }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_arrayinit }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_initf }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_chiplet_init3 }},
+ };
+
+static istepMap_t g_istep3PtrTbl[ ISTEP3_MAX_SUBSTEPS ] =
+ {
+ { &istepWithProc, { .procHwp = &p9_sbe_chiplet_reset }},
+ { &istepWithProc, { .procHwp = &p9_sbe_gptr_time_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_chiplet_pll_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_chiplet_pll_setup }},
+ { &istepWithProc, { .procHwp = &p9_sbe_repr_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_chiplet_init }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_arrayinit }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_enable_ridi }},
+ { &istepWithProc, { .procHwp = &p9_sbe_setup_boot_freq }},
+ { &istepWithProc, { .procHwp = &p9_sbe_nest_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_nest_startclocks }},
+ { &istepWithProc, { .procHwp = &p9_sbe_nest_enable_ridi }},
+ { &istepWithProc, { .procHwp = &p9_sbe_io_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_startclock_chiplets }},
+ { &istepWithProc, { .procHwp = &p9_sbe_scominit }},
+ { &istepWithProc, { .procHwp = &p9_sbe_lpc_init }},
+ { &istepWithProc, { .procHwp = &p9_sbe_fabricinit }},
+ { &istepCheckSbeMaster, NULL },
+ { &istepWithProc, { .procHwp = &p9_sbe_mcs_setup }},
+ { &istepSelectEx, NULL },
+ };
+static istepMap_t g_istep4PtrTbl[ ISTEP4_MAX_SUBSTEPS ] =
+ {
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_poweron} },
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_chiplet_reset } },
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_chiplet_l3_dcc_setup }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_gptr_time_initf }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_dpll_initf }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_dpll_setup }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_dcc_skewadjust_setup }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_chiplet_init }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_repair_initf }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_arrayinit }},
+ { &istepNoOp, NULL }, // DFT Only
+ { &istepNoOp, NULL }, // DFT Only
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_initf }},
+ { &istepWithEqConditional, { .eqHwp = &p9_hcd_cache_startclocks }},
+ { &istepWithEqConditional, { .eqHwp = &p9_hcd_cache_scominit }},
+ { &istepWithEqConditional, { .eqHwp = &p9_hcd_cache_scomcust }},
+ { &istepNoOp, NULL }, // Runtime only
+ { &istepNoOp, NULL }, // Runtime only
+ { &istepNoOp, NULL }, // stub for SBE
+ { &istepNoOp, NULL }, // stub for SBE
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_poweron }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_chiplet_reset }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_gptr_time_initf }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_chiplet_init }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_repair_initf }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_arrayinit }},
+ { &istepNoOp, NULL }, // DFT Only
+ { &istepNoOp, NULL }, // DFT Only
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_initf }},
+ { &istepWithCoreConditional,
+ { .coreHwp = &p9_hcd_core_startclocks }},
+ { &istepWithCoreConditional, { .coreHwp = &p9_hcd_core_scominit }},
+ { &istepWithCoreConditional, { .coreHwp = &p9_hcd_core_scomcust }},
+ { &istepNoOp, NULL },
+ { &istepNoOp, NULL },
+ };
+
+// TODO via RTC 135345
+// Add the support for istep 5 HWP
+static istepMap_t g_istep5PtrTbl[ ISTEP5_MAX_SUBSTEPS ]
+ {
+ { &istepLoadBootLoader, NULL },
+ { &istepStartInstruction, { .coreHwp = &p9_sbe_instruct_start }},
+ };
+
+// Functions
+//----------------------------------------------------------------------------
+uint32_t sbeHandleIstep (uint8_t *i_pArg)
+{
+ #define SBE_FUNC "sbeHandleIstep "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ ReturnCode fapiRc = FAPI2_RC_SUCCESS;
+ uint32_t len = 0;
+ sbeIstepReqMsg_t req;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeResponseFfdc_t ffdc;
+
+ // NOTE: In this function we will have two loops
+ // First loop will deque data and prepare the response
+ // Second response will enque the data on DS FIFO
+ //loop 1
+ do
+ {
+ len = sizeof( req )/sizeof(uint32_t);
+ rc = sbeUpFifoDeq_mult ( len, (uint32_t *)&req);
+ if (rc != SBE_SEC_OPERATION_SUCCESSFUL) //FIFO access issue
+ {
+ SBE_ERROR(SBE_FUNC"FIFO dequeue failed, rc[0x%X]", rc);
+ break;
+ }
+
+ if( false == validateIstep( req.major, req.minor ) )
+ {
+ SBE_ERROR(SBE_FUNC" Invalid Istep. major:0x%08x"
+ " minor:0x%08x", req.major, req.minor);
+ // @TODO via RTC 132295.
+ // Need to change code asper better error handling.
+ respHdr.setStatus( SBE_PRI_INVALID_DATA,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ break;
+ }
+
+ fapiRc = sbeExecuteIstep( req.major, req.minor );
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" sbeExecuteIstep() Failed. major:0x%08x"
+ " minor:0x%08x", req.major, req.minor);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+
+ }while(0);
+
+ //loop 2
+ do
+ {
+ // FIFO error
+ if ( rc )
+ {
+ break;
+ }
+
+ rc = sbeDsSendRespHdr(respHdr, ffdc);
+ }while(0);
+
+ if( rc )
+ {
+ SBE_ERROR( SBE_FUNC"Failed. rc[0x%X]", rc);
+ }
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+// @note This is the responsibilty of caller to verify major/minor
+// number before calling this function
+
+// @TODO via RTC 129077.
+// This function should check for system checkstop as well.
+ReturnCode sbeExecuteIstep (const uint8_t i_major, const uint8_t i_minor)
+{
+ #define SBE_FUNC "sbeExecuteIstep "
+ SBE_INFO(SBE_FUNC"Major number:0x%x minor number:0x%x",
+ i_major, i_minor );
+
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ switch( i_major )
+ {
+ case SBE_ISTEP2:
+ rc = (g_istep2PtrTbl[i_minor-1].istepWrapper)(
+ g_istep2PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP3:
+ rc = (g_istep3PtrTbl[i_minor-1].istepWrapper)(
+ g_istep3PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP4:
+ rc = (g_istep4PtrTbl[i_minor-1].istepWrapper)(
+ g_istep4PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP5:
+ rc = (g_istep5PtrTbl[i_minor-1].istepWrapper)(
+ g_istep5PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ // We should never reach here as before calling this validation has
+ // been done.
+ default:
+ assert(0);
+ break;
+ }
+
+ (void)SbeRegAccess::theSbeRegAccess().updateSbeStep(i_major, i_minor);
+
+ if(rc != FAPI2_RC_SUCCESS)
+ {
+ // If IPLing State
+ uint64_t l_state = SbeRegAccess::theSbeRegAccess().getSbeState();
+ if(l_state == SBE_STATE_IPLING)
+ {
+ (void)SbeRegAccess::theSbeRegAccess().
+ stateTransition(SBE_DUMP_FAILURE_EVENT);
+ }
+ }
+
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+bool validateIstep (const uint8_t i_major, const uint8_t i_minor)
+{
+ bool valid = true;
+ do
+ {
+ if( 0 == i_minor )
+ {
+ valid = false;
+ break;
+ }
+
+ if((SBE_ROLE_SLAVE == g_sbeRole) &&
+ ((SBE_ISTEP_LAST_SLAVE < i_major) ||
+ ((SBE_ISTEP_LAST_SLAVE == i_major) &&
+ (SLAVE_LAST_MINOR_ISTEP < i_minor)
+ )))
+ {
+ // Cannot run beyond 3.20 on a slave SBE
+ valid = false;
+ break;
+ }
+
+ switch( i_major )
+ {
+ case SBE_ISTEP2:
+ // istep 2.1 loads image to PIBMEM
+ // So SBE control loop can not execute istep 2.1.
+ if(( i_minor > ISTEP2_MAX_SUBSTEPS ) || ( i_minor == 1) )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP3:
+ if( i_minor > ISTEP3_MAX_SUBSTEPS ) { valid = false; } ;
+ break;
+
+ case SBE_ISTEP4:
+ if( i_minor > ISTEP4_MAX_SUBSTEPS )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP5:
+ if( i_minor > ISTEP5_MAX_SUBSTEPS )
+ {
+ valid = false;
+ }
+ break;
+
+ default:
+ valid= false;
+ break;
+ }
+ } while(0);
+
+ return valid;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepAttrSetup( sbeIstepHwp_t i_hwp)
+{
+ SBE_ENTER("istepAttrSetup");
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ assert( NULL != i_hwp.procHwp );
+ rc = i_hwp.procHwp(proc);
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ break;
+ }
+ // Apply the gard records
+ rc = plat_ApplyGards();
+ }while(0);
+ SBE_EXIT("istepAttrSetup");
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithProc( sbeIstepHwp_t i_hwp)
+{
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ assert( NULL != i_hwp.procHwp );
+ return i_hwp.procHwp(proc);
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepSelectEx( sbeIstepHwp_t i_hwp)
+{
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ // TODO via RTC 135345
+ // Once multicast targets are supported, we may need to pass
+ // p9selectex::ALL as input.
+ return p9_sbe_select_ex_hwp(proc, p9selectex::SINGLE);
+}
+
+//----------------------------------------------------------------------------
+
+
+ReturnCode istepWithEq( sbeIstepHwp_t i_hwp)
+{
+ // TODO via RTC 135345
+ // Curently we are passing Hard code eq target. Finally it is
+ // going to be a multicast target. Once multicast support is
+ // present, use the right target.
+ fapi2::Target<fapi2::TARGET_TYPE_EQ > eqTgt;
+ // Put this in scope so that vector can be freed up before calling hwp.
+ {
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ auto eqList = proc.getChildren<fapi2::TARGET_TYPE_EQ>();
+ // As it is workaround lets assume there will always be atleast one
+ // functional eq. No need to validate.
+ eqTgt = eqList[0];
+ }
+
+ assert( NULL != i_hwp.eqHwp );
+ return i_hwp.eqHwp( eqTgt );
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithCore( sbeIstepHwp_t i_hwp)
+{
+ // TODO via RTC 135345
+ // Curently we are passing Hard code core target. Finally it is
+ // going to be a multicast target. Once multicast support is
+ // present, use the right target.
+ fapi2::Target<fapi2::TARGET_TYPE_CORE > coreTgt;
+ // Put this in scope so that vector can be freed up before calling hwp.
+ {
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ auto coreList = proc.getChildren<fapi2::TARGET_TYPE_CORE>();
+ // As it is workaround lets assume there will always be atleast one
+ // functional ec. No need to validate.
+ coreTgt = coreList[0];
+ }
+ assert( NULL != i_hwp.coreHwp );
+ return i_hwp.coreHwp( coreTgt );
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithEqConditional( sbeIstepHwp_t i_hwp)
+{
+ SBE_ENTER("istepWithEqCondtional");
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM > sysTgt;
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ uint8_t iplPhase = ENUM_ATTR_SYSTEM_IPL_PHASE_HB_IPL;
+ FAPI_ATTR_GET(ATTR_SYSTEM_IPL_PHASE, sysTgt, iplPhase);
+ if( ENUM_ATTR_SYSTEM_IPL_PHASE_CACHE_CONTAINED == iplPhase )
+ {
+ break;
+ }
+ rc = istepWithEq(i_hwp);
+ }while(0);
+ SBE_EXIT("istepWithEqCondtional");
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithCoreConditional( sbeIstepHwp_t i_hwp)
+{
+ SBE_ENTER("istepWithCoreCondtional");
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM > sysTgt;
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ uint8_t iplPhase = ENUM_ATTR_SYSTEM_IPL_PHASE_HB_IPL;
+ FAPI_ATTR_GET(ATTR_SYSTEM_IPL_PHASE, sysTgt, iplPhase);
+ if( ENUM_ATTR_SYSTEM_IPL_PHASE_CACHE_CONTAINED == iplPhase )
+ {
+ break;
+ }
+ rc = istepWithCore(i_hwp);
+ }while(0);
+ SBE_EXIT("istepWithCoreCondtional");
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepLoadBootLoader( sbeIstepHwp_t i_hwp)
+{
+ // Get master Ex
+ uint8_t exId = 0;
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ FAPI_ATTR_GET(fapi2::ATTR_MASTER_EX,proc,exId);
+ fapi2::Target<fapi2::TARGET_TYPE_EX >
+ exTgt(plat_getTargetHandleByInstance<fapi2::TARGET_TYPE_EX>(exId));
+ // Get hbbl section
+ P9XipHeader *hdr = getXipHdr();
+ P9XipSection *hbblSection = &(hdr->iv_section[P9_XIP_SECTION_SBE_HBBL]);
+
+ ReturnCode rc = p9_sbe_load_bootloader( proc, exTgt, hbblSection->iv_size,
+ getSectionAddr(hbblSection) );
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepStartInstruction( sbeIstepHwp_t i_hwp)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ rc = istepWithCore(i_hwp);
+ if(rc == FAPI2_RC_SUCCESS)
+ {
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_RUNTIME_EVENT);
+ }
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepCheckSbeMaster( sbeIstepHwp_t i_hwp)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ g_sbeRole = SbeRegAccess::theSbeRegAccess().isSbeSlave() ?
+ SBE_ROLE_SLAVE : SBE_ROLE_MASTER;
+ SBE_INFO("stepCheckSbeMaster g_sbeRole [%x]", g_sbeRole);
+ if(SBE_ROLE_SLAVE == g_sbeRole)
+ {
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_RUNTIME_EVENT);
+ }
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepNoOp( sbeIstepHwp_t i_hwp)
+{
+ SBE_INFO("istepNoOp");
+ return FAPI2_RC_SUCCESS ;
+}
+
+// Only allowed in PLCK Mode, since FFDC State mode is set only in PLCK
+//----------------------------------------------------------------------------
+uint32_t sbeContinueBoot (uint8_t *i_pArg)
+{
+ #define SBE_FUNC "sbeContinueBoot "
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t len = 0;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ rc = sbeUpFifoDeq_mult (len, NULL);
+ if(rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // let command processor routine handle the RC
+ break;
+ }
+
+ uint32_t distance = 1;
+ len = sizeof(respHdr)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &respHdr);
+ if (rc)
+ {
+ break;
+ }
+ distance += len;
+
+ len = sizeof(distance)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, &distance);
+ if (rc)
+ {
+ break;
+ }
+ rc = sbeDownFifoSignalEot();
+ if (rc)
+ {
+ break;
+ }
+
+ // Expecting this to be in PLCK Mode and not in Istep mode
+ if(SbeRegAccess::theSbeRegAccess().isDestBitRuntime())
+ {
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_CONTINUE_BOOT_RUNTIME_EVENT);
+ // Nothing to do here.
+ }
+ else
+ {
+ SBE_INFO(SBE_FUNC"Continuous IPL Mode set... IPLing");
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_CONTINUE_BOOT_PLCK_EVENT);
+ sbeDoContinuousIpl();
+ }
+ }while(0);
+
+ SBE_DEBUG(SBE_FUNC "RC = 0x%08X", rc);
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+void sbeDoContinuousIpl()
+{
+ #define SBE_FUNC "sbeDoContinuousIpl "
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ // An array that holds the max number of minor steps per major step
+ const uint8_t l_minorSteps[] =
+ {
+ ISTEP2_MAX_SUBSTEPS,
+ ISTEP3_MAX_SUBSTEPS,
+ ISTEP4_MAX_SUBSTEPS,
+ ISTEP5_MAX_SUBSTEPS
+ };
+
+ // Where does each minor istep start from?
+ const uint8_t l_minorStartStep[] =
+ {
+ ISTEP2_MINOR_START,
+ ISTEP_MINOR_START,
+ ISTEP_MINOR_START,
+ ISTEP_MINOR_START
+ };
+
+ // Set SBE state as IPLing
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_PLCK_EVENT);
+ bool l_done = false;
+ // Run isteps
+ for(uint8_t l_major = SBE_ISTEP_FIRST;
+ (l_major <= SBE_ISTEP_LAST_MASTER) &&
+ (false == l_done);
+ ++l_major)
+ {
+ for(uint8_t l_minor = l_minorStartStep[l_major - SBE_ISTEP_FIRST];
+ l_minor <= l_minorSteps[l_major - SBE_ISTEP_FIRST];
+ ++l_minor)
+ {
+ l_rc = sbeExecuteIstep(l_major, l_minor);
+ if(l_rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC"Failed istep execution in plck mode: "
+ "Major: %d, Minor: %d", l_major, l_minor);
+ l_done = true;
+ break;
+ }
+ // Check if we are at step 3.20 on the slave SBE
+ if(((SBE_ISTEP_LAST_SLAVE == l_major) &&
+ (SLAVE_LAST_MINOR_ISTEP == l_minor)) &&
+ (SBE_ROLE_SLAVE == g_sbeRole))
+ {
+ l_done = true;
+ break;
+ }
+ }
+ }
+ } while(false);
+ // Store l_rc in a global variable that will be a part of the SBE FFDC
+ g_iplFailRc = l_rc;
+ SBE_EXIT(SBE_FUNC);
+ #undef SBE_FUNC
+}
+
+// TODO - RTC 133367
+//----------------------------------------------------------------------------
+uint32_t sbeEnterMpipl(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeEnterMpipl "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t len = 0;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ l_rc = sbeUpFifoDeq_mult (len, NULL);
+ if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL )
+ {
+ // Let command processor routine to handle the RC
+ break;
+ }
+
+ sbeResponseFfdc_t l_ffdc;
+ l_rc = sbeDsSendRespHdr( l_respHdr, l_ffdc);
+
+ // set state to MPIPL Wait
+ (void)SbeRegAccess::theSbeRegAccess().
+ stateTransition(SBE_ENTER_MPIPL_EVENT);
+
+ //TODO RTC-123696 MPIPL Related procedure/steps
+ }while(0);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+// TODO - RTC 133367
+//----------------------------------------------------------------------------
+uint32_t sbeContinueMpipl(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeContinueMpipl "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t len = 0;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ l_rc = sbeUpFifoDeq_mult (len, NULL);
+ if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL )
+ {
+ // Let command processor routine to handle the RC
+ break;
+ }
+
+ sbeResponseFfdc_t l_ffdc;
+ l_rc = sbeDsSendRespHdr( l_respHdr, l_ffdc);
+
+ //TODO RTC-134278 Continue MPIPL Related procedure/steps
+
+ // TODO - Once continue steps are over, it will trigger the
+ // istep5.2 and transition to runtime will happen
+
+ }while(0);
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
diff --git a/src/sbefw/sbecmdiplcontrol.H b/src/sbefw/sbecmdiplcontrol.H
new file mode 100644
index 00000000..e06757c5
--- /dev/null
+++ b/src/sbefw/sbecmdiplcontrol.H
@@ -0,0 +1,117 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdiplcontrol.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdiplcontrol.H
+ *
+ * @brief This file contains the SBE command details
+ *
+ */
+
+#ifndef __SBEFW_SBECMDIPLCONTROL_H
+#define __SBEFW_SBECMDIPLCONTROL_H
+
+#include <stdint.h>
+
+namespace fapi2
+{
+ class ReturnCode;
+}
+
+/**
+ * @brief execute istep chipop (0xA101)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeHandleIstep(uint8_t *i_pArg);
+
+
+/**
+ * @brief Handles Sbe continue boot after collect ffdc chip-op (0xA102)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeContinueBoot(uint8_t *i_pArg);
+
+
+/**
+ * @brief Executes IPL steps in continuous mode.
+ *
+ * @par On the master SBE, this will run
+ * all steps from 2.2 to 5.2. On the slave SBE, it runs all steps from 2.2
+ * to 3.18.
+ * In case an error is encountered, the execution is aborted.
+ */
+void sbeDoContinuousIpl();
+
+/**
+ * @brief Handles Sbe Enter Mpipl chip-op (0xA901)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeEnterMpipl(uint8_t *i_pArg);
+
+/**
+ * @brief Handles Sbe Continue Mpipl chip-op (0xA902)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeContinueMpipl(uint8_t *i_pArg);
+
+/**
+ * @brief Handles Sbe Get FFDC chip-op (0xA801)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetSbeFfdc(uint8_t *i_pArg);
+
+/**
+ * @brief Handles Sbe Get FFDC chip-op (0xA803)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetFreqSupported(uint8_t *i_pArg);
+
+/**
+ * @brief Handles Sbe Abort chip-op (0xA804)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeAbort(uint8_t *i_pArg);
+
+
+#endif // __SBEFW_SBECMDIPLCONTROL_H
diff --git a/src/sbefw/sbecmdmemaccess.C b/src/sbefw/sbecmdmemaccess.C
new file mode 100644
index 00000000..942bb72d
--- /dev/null
+++ b/src/sbefw/sbecmdmemaccess.C
@@ -0,0 +1,778 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdmemaccess.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdmemaccess.C
+ *
+ * @brief This file contains the SBE Memory Access chipOps
+ *
+ */
+
+#include "sbecmdmemaccess.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbeFifoMsgUtils.H"
+#include "sbeutil.H"
+
+#include "fapi2.H"
+
+#include "p9_pba_setup.H"
+#include "p9_adu_setup.H"
+#include "p9_pba_access.H"
+#include "p9_adu_access.H"
+
+
+using namespace fapi2;
+
+// Buffer requirement for ADU and PBA on the stack
+static const uint32_t MAX_ADU_BUFFER = 40;
+static const uint32_t MAX_PBA_BUFFER = 32;
+// PBA / ADU Granule size as per the HWP Requirement
+static const uint32_t PBA_GRAN_SIZE_BYTES = 128;
+static const uint32_t ADU_GRAN_SIZE_BYTES = 8;
+
+// Multiplier factor with respect to the FIFO length
+static const uint32_t ADU_SIZE_MULTIPLIER_FOR_LEN_ALIGNMENT = 2;
+static const uint32_t PBA_SIZE_MULTIPLIER_FOR_LEN_ALIGNMENT = 32;
+
+//Default EX Target ChipletId to be used in PBA by default
+static const uint32_t PBA_DEFAULT_EX_CHIPLET_ID = 7;
+
+/**
+ * @brief static definition of parameters passed in adu chip-ops
+ */
+static const uint32_t SBE_ADU_LOCK_TRIES = 3;
+
+// Transaction size (choice is 1, 2, 4, or 8)
+// 0b00: TSIZE_1
+// 0b01: TSIZE_2
+// 0b10: TSIZE_4
+// 0b11: TSIZE_8
+static const uint32_t SBE_ADU_TRANSACTION_SIZE = 3;
+static const bool SBE_ADU_LEAVE_DIRTY_BOOL = false;
+static const bool SBE_ADU_LOCK_PICK_BOOL = false;
+
+/**
+ * @brief Mask used to build the Flag struct for ADU chip-op
+ **/
+static const uint32_t ADU_LOCK_TRIES_SHIFT = 16;
+static const uint32_t ADU_TRANSACTION_SIZE_SHIFT = 20;
+static const uint32_t ADU_ECC_OVERRIDE_BIT_SHIFT = 22;
+static const uint32_t ADU_ECC_REQUIRED_BIT_SHIFT = 23;
+static const uint32_t ADU_ITAG_REQUIRED_BIT_SHIFT = 24;
+static const uint32_t ADU_FAST_MODE_SHIFT = 25;
+static const uint32_t ADU_LEAVE_DIRTY_SHIFT = 26;
+static const uint32_t ADU_LOCK_PICK_SHIFT = 27;
+static const uint32_t ADU_AUTO_INCR_SHIFT = 28;
+static const uint32_t CACHE_INHIBIT_MODE_SHIFT = 29;
+
+// Fast Mode bit shift for PBA
+static const uint32_t PBA_FAST_MODE_SHIFT = 31;
+
+///////////////////////////////////////////////////////////////////////
+// @brief align4ByteWordLength - Internal Method to this file
+// Align the length passed and return number of words
+//
+// @param [in] i_len, length pass from user in Bytes
+//
+// @return Number of words (number of 4byte length)
+///////////////////////////////////////////////////////////////////////
+inline uint32_t align4ByteWordLength(uint32_t i_len)
+{
+ if(i_len % 4 != 0)
+ {
+ i_len = i_len + (4 - (i_len % 4));
+ }
+ return(i_len/4);
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief calInterAduLenForUpFifo - Internal Method to this file
+// Calculate Intermediate Adu Data length for Upstream Fifo
+//
+// @param [in] i_mod, Modulus number from user, (from numGranules % 4)
+// could be any values from 1,2,3
+// @param [in] i_itag, Itag flag
+// @param [in] i_ecc, Ecc flag
+//
+// @return length in bytes for intermediate ADU length
+///////////////////////////////////////////////////////////////////////
+inline uint32_t calInterAduLenForUpFifo(uint8_t i_mod, bool i_itag, bool i_ecc)
+{
+ //Default init length with either Ecc or Itag
+ uint32_t l_len =
+ ((ADU_GRAN_SIZE_BYTES + 1) * (1 + i_mod));
+ // If ECC and iTag bit is also part of the buffer
+ if(i_itag && i_ecc)
+ {
+ l_len = l_len + (1 + i_mod);
+ }
+ return (l_len);
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeAduLenInUpStreamFifo - Internal Method to this file
+// Calculate the Final Size which is write/read to/from HWP
+//
+// @param [in] i_numGranules, Number of granules read/write
+// @param [in] i_itag, Itag flag
+// @param [in] i_ecc, Ecc flag
+//
+// @return Length in bytes for ADU to be put in Upstream FIFO
+///////////////////////////////////////////////////////////////////////
+inline uint32_t sbeAduLenInUpStreamFifo(uint32_t i_numGranules,
+ bool i_itag,
+ bool i_ecc)
+{
+ uint32_t l_respLen = i_numGranules * ADU_GRAN_SIZE_BYTES;
+ if(i_itag)
+ {
+ // Add one byte for Itag for Each Granule Completed
+ l_respLen = l_respLen + i_numGranules;
+ }
+ if(i_ecc)
+ {
+ // Add one byte for Ecc for Each Granule Completed
+ l_respLen = l_respLen + i_numGranules;
+ }
+ return l_respLen;
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief flushUpstreamFifo - Internal Method to this file, to flush
+// out the upstream fifo
+//
+// @param [in] i_fapiRc, Fapi RC
+//
+// @return RC from the underlying FIFO utility
+///////////////////////////////////////////////////////////////////////
+inline uint32_t flushUpstreamFifo (const uint32_t &i_fapiRc)
+{
+ uint32_t l_len2dequeue = 0;
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ if ( i_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL,
+ true, true);
+ }
+ // For other success paths, just attempt to offload
+ // the next entry, which is supposed to be the EOT entry
+ else
+ {
+ l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL, true);
+ }
+ return l_rc;
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// @brief constructAduFlag - Internal Method to this file, to construct
+// ADU flag as the HWP expects
+//
+// @param [in] i_hdr, Message Request Header
+// @param [in] i_isFlagRead, Read/Write Flag
+//
+// @return Constructed ADU Flag
+///////////////////////////////////////////////////////////////////////
+uint32_t constructAduFlag(const sbeMemAccessReqMsgHdr_t & i_hdr,
+ const bool i_isFlagRead)
+{
+ #define SBE_FUNC " constructAduFlag"
+
+ // Fast Mode / Ecc mode / Cache Inhibit Mode / Auto Increment
+ // required in ADU operations.
+ bool l_isFastMode = i_hdr.isFastModeSet();
+ bool l_isCacheInhibitMode = i_hdr.isCacheInhibitModeFlagSet();
+ bool l_isItagBit = i_hdr.isItagFlagSet();
+ bool l_isAutoIncr = i_hdr.isAutoIncrModeSet();
+ bool l_isEccRequiredMode = false;
+ bool l_isEccOverrideMode = false;
+
+ if(!i_isFlagRead) // ECC override in write mode
+ {
+ l_isEccOverrideMode = i_hdr.isEccOverrideFlagSet();
+ if(l_isEccOverrideMode)
+ {
+ l_isEccRequiredMode = true;
+ }
+ }
+ else // ECC required in read mode
+ {
+ l_isEccRequiredMode = i_hdr.isEccFlagSet();
+ }
+
+ // Construct the flag required for adu setup
+ uint32_t l_aduSetupFlag =
+ ( (l_isCacheInhibitMode << CACHE_INHIBIT_MODE_SHIFT) |
+ // 3-bit of Cache mode placed in 31-30-29 bits
+ (l_isAutoIncr << ADU_AUTO_INCR_SHIFT) |
+ // 1-bit Auto increment placed at 28th bit
+ (SBE_ADU_LOCK_PICK_BOOL << ADU_LOCK_PICK_SHIFT) |
+ // 1-bit pick lock placed at 27th bit
+ (SBE_ADU_LEAVE_DIRTY_BOOL << ADU_LEAVE_DIRTY_SHIFT) |
+ // 1-bit leave dirty placed at 26th bit
+ (l_isFastMode << ADU_FAST_MODE_SHIFT) |
+ // 1-bit Fast mode placed at 25th bit
+ (l_isItagBit << ADU_ITAG_REQUIRED_BIT_SHIFT) |
+ // 1-bit itag placed at 24th bit
+ (l_isEccRequiredMode << ADU_ECC_REQUIRED_BIT_SHIFT) |
+ // 1-bit ecc required at 23rd bit
+ (l_isEccOverrideMode << ADU_ECC_OVERRIDE_BIT_SHIFT) |
+ // 1-bit ecc override at 22nd bit
+ (SBE_ADU_TRANSACTION_SIZE << ADU_TRANSACTION_SIZE_SHIFT) |
+ // 2-bit Transcation size at 21-20th bits
+ (SBE_ADU_LOCK_TRIES << ADU_LOCK_TRIES_SHIFT) );
+ // 4-bit Lock Tries at 19-18-17-16 bits
+
+ SBE_INFO(SBE_FUNC "Cache[%d] Itag[%d] AutoIncr[%d] FastMode[%d] ",
+ l_isCacheInhibitMode,l_isItagBit,l_isAutoIncr,l_isFastMode);
+ SBE_INFO(SBE_FUNC "EccRequiredMode[%d] EccOverrideMode[%d] EccOverrideByte"
+ "[0x%02X] AduSetupFlag[0x%04X]",l_isEccRequiredMode,l_isEccOverrideMode,
+ i_hdr.eccByte, l_aduSetupFlag);
+
+ return (l_aduSetupFlag);
+ #undef SBE_FUNC
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief processPbaRequest - Internal Method to this file,
+// To process the PBA Access request
+//
+// @param [in] i_hdr, Message Request Header
+// @param [in] i_isFlagRead, Read/Write Flag
+//
+// @return RC from the method
+///////////////////////////////////////////////////////////////////////
+uint32_t processPbaRequest(const sbeMemAccessReqMsgHdr_t &i_hdr,
+ const bool i_isFlagRead)
+{
+ #define SBE_FUNC " processPbaRequest "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ ReturnCode l_fapiRc = FAPI2_RC_SUCCESS;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+ sbeResponseFfdc_t l_ffdc;
+
+ // Default for PBA
+ uint32_t l_sizeMultiplier = PBA_SIZE_MULTIPLIER_FOR_LEN_ALIGNMENT;
+ uint32_t l_granuleSize = PBA_GRAN_SIZE_BYTES;
+ uint64_t l_addr = i_hdr.getAddr();
+
+ // Proc Chip Target
+ Target<fapi2::TARGET_TYPE_PROC_CHIP> l_proc = plat_getChipTarget();
+ // Default EX Target Init..Not changing it for the time being
+ Target<fapi2::TARGET_TYPE_EX > l_ex((uint64_t)PBA_DEFAULT_EX_CHIPLET_ID);
+
+ // Determine the access flags
+ // Fast mode flag
+ bool l_isFastMode = i_hdr.isFastModeSet();
+ //LCO Mode for PBA-Put
+ bool l_isLcoMode = i_hdr.isPbaLcoModeSet();
+ if(l_isLcoMode)
+ {
+ //Derive the EX target from the input Core Chiplet Id
+ //Core0/1 -> EX0, Core2/3 -> EX1, Core4/5 -> EX2, Core6/7 -> EX3
+ //..so on
+ l_ex = plat_getTargetHandleByChipletNumber<fapi2::TARGET_TYPE_EX>
+ (i_hdr.coreChipletId);
+ }
+ // By default, ex_chipletId printed below won't be used unless accompanied
+ // by LCO_mode.
+ SBE_INFO(SBE_FUNC "FAST_Mode[%d] LCO_Mode[%d] EX_ChipletId[%d]",
+ l_isFastMode, l_isLcoMode, (i_hdr.coreChipletId)/2);
+
+ // The max granule size for which the ADU/PBA interface if configured
+ uint32_t l_numGranules = 0;
+ // Keeps track of number of granules sent to HWP
+ uint64_t l_granulesCompleted = 0;
+
+ // Input Data length in alignment with PBA (128 Bytes)
+ uint64_t l_lenCacheAligned = i_hdr.getDataLenCacheAlign();
+ SBE_DEBUG(SBE_FUNC "Data Aligned Len / Number of data granules = %d",
+ l_lenCacheAligned);
+
+ while (l_granulesCompleted < l_lenCacheAligned)
+ {
+ // Call the PBA setup HWP
+ l_fapiRc = p9_pba_setup(
+ l_proc,
+ l_ex,
+ l_addr,
+ i_isFlagRead,
+ ((l_isFastMode) ? (1<<PBA_FAST_MODE_SHIFT) : 0),
+ l_numGranules);
+
+ // if p9_pba_setup returns error
+ if(l_fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC" p9_pba_setup Failed");
+ // Respond with HWP FFDC
+ l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION );
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+
+ // Assumption is Hwp won't return zero for Num Granules
+ assert(0 != l_numGranules);
+
+ SBE_INFO(SBE_FUNC "Hwp returned l_numGranules=[0x%08X]",l_numGranules);
+ uint64_t l_numAcc = 0;
+
+ if (l_numGranules < (l_lenCacheAligned - l_granulesCompleted))
+ {
+ l_numAcc = l_numGranules;
+ }
+ else
+ {
+ l_numAcc = l_lenCacheAligned - l_granulesCompleted;
+ }
+
+ // 128Byte granule for PBA access
+ uint32_t l_dataFifo[MAX_PBA_BUFFER] = {0};
+
+ uint64_t l_numCurrAcc = 0;
+ while (l_numCurrAcc < l_numAcc)
+ {
+ bool l_lastGran = (l_numCurrAcc == (l_numAcc-1)) ? true : false;
+ bool l_firstGran = (l_numCurrAcc == 0) ? true : false;
+
+ // If this is putmem request, read input data from the upstream FIFO
+ if (!i_isFlagRead)
+ {
+ // l_sizeMultiplier * 4B Upstream FIFO = Granule size 128B
+ uint32_t l_len2dequeue = l_sizeMultiplier;
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue,
+ (uint32_t *)&l_dataFifo,
+ false);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ }
+ // Call PBA access
+ l_fapiRc = p9_pba_access(
+ l_proc,
+ l_addr,
+ i_isFlagRead,
+ ((l_isFastMode) ? (1<<PBA_FAST_MODE_SHIFT) : 0),
+ l_firstGran,
+ l_lastGran,
+ (uint8_t *)&l_dataFifo);
+
+ // if p9_pba_access returns error
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" p9_pba_access Failed");
+ // Respond with HWP FFDC
+ l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION );
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+
+ // If this is a getmem request,
+ // need to push the data into the downstream FIFO
+ if (i_isFlagRead)
+ {
+ // Number of 4Bytes to put, to align with Granule Size
+ uint32_t l_len = l_sizeMultiplier; // l_len*4 = Granule Size
+ l_rc = sbeDownFifoEnq_mult (l_len, (uint32_t *)&l_dataFifo);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ }
+ l_granulesCompleted++;
+ l_numCurrAcc++;
+ } // End inner while loop
+
+ if ( (l_fapiRc != FAPI2_RC_SUCCESS) ||
+ (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) )
+ {
+ break;
+ }
+ l_addr += l_granuleSize * l_granulesCompleted;
+ } // End..while (l_granulesCompleted < l_lenCacheAligned);
+
+ // Now build and enqueue response into downstream FIFO
+ do
+ {
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ // If there was a HWP failure for putmem request,
+ // need to Flush out upstream FIFO, until EOT arrives
+ if (!i_isFlagRead)
+ {
+ l_rc = flushUpstreamFifo(l_fapiRc);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ }
+
+ // first enqueue the length of data actually written
+ uint32_t l_len = 1;
+ uint32_t l_respLen = l_granulesCompleted * l_granuleSize;
+
+ SBE_INFO(SBE_FUNC "Total length Pushed for ChipOp [%d]", l_respLen);
+ l_rc = sbeDownFifoEnq_mult ( l_len, &l_respLen );
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+
+ l_rc = sbeDsSendRespHdr( l_respHdr, l_ffdc);
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// @brief processAduRequest - Internal Method to this file,
+// To process the ADU Access request
+//
+// @param [in] i_hdr, Message Request Header
+// @param [in] i_isFlagRead, Read/Write Flag
+//
+// @return RC from the method
+///////////////////////////////////////////////////////////////////////
+uint32_t processAduRequest(const sbeMemAccessReqMsgHdr_t &i_hdr,
+ const bool i_isFlagRead)
+{
+ #define SBE_FUNC " processAduRequest "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ ReturnCode l_fapiRc = FAPI2_RC_SUCCESS;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+ sbeResponseFfdc_t l_ffdc;
+
+ // Default for ADU
+ uint32_t l_sizeMultiplier = ADU_SIZE_MULTIPLIER_FOR_LEN_ALIGNMENT;
+ uint32_t l_granuleSize = ADU_GRAN_SIZE_BYTES;
+
+ // Adu Setup Flag
+ uint32_t l_aduSetupFlags = constructAduFlag(i_hdr, i_isFlagRead);
+
+ // For local Use
+ bool l_isEccMode = i_hdr.isEccFlagSet();
+ bool l_isItagMode = i_hdr.isItagFlagSet();
+ uint64_t l_addr = i_hdr.getAddr();
+
+ // Proc Chip Target
+ Target<fapi2::TARGET_TYPE_PROC_CHIP> l_proc = plat_getChipTarget();
+
+ // The max granule size for which the ADU/PBA interface if configured
+ uint32_t l_numGranules = 0;
+ // Keeps track of number of granules sent to HWP
+ uint64_t l_granulesCompleted = 0;
+
+ // Input Data length in alignment with PBA (128 Bytes)
+ uint64_t l_lenCacheAligned = i_hdr.getDataLenCacheAlign();
+ SBE_DEBUG(SBE_FUNC "Data Aligned Len / Number of data granules = %d",
+ l_lenCacheAligned);
+
+ while (l_granulesCompleted < l_lenCacheAligned)
+ {
+ // Call the ADU setup HWP
+ l_fapiRc = p9_adu_setup (l_proc,
+ l_addr,
+ i_isFlagRead,
+ l_aduSetupFlags,
+ l_numGranules);
+ // if p9_adu_setup returns error
+ if( (l_fapiRc != FAPI2_RC_SUCCESS) )
+ {
+ SBE_ERROR(SBE_FUNC" p9_adu_setup Failed");
+ // Respond with HWP FFDC
+ l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION );
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+ // Assumption is Hwp won't return zero for Num Granules
+ assert(0 != l_numGranules);
+
+ SBE_INFO(SBE_FUNC "Hwp returned l_numGranules=[0x%08X]",l_numGranules);
+ uint64_t l_numAcc = 0;
+
+ if (l_numGranules < (l_lenCacheAligned - l_granulesCompleted))
+ {
+ l_numAcc = l_numGranules;
+ }
+ else
+ {
+ l_numAcc = l_lenCacheAligned - l_granulesCompleted;
+ }
+
+ // 8Byte granule for ADU access
+ uint32_t l_dataFifo[MAX_ADU_BUFFER] = {0};
+
+ uint64_t l_numCurrAcc = 0;
+ while (l_numCurrAcc < l_numAcc)
+ {
+ bool l_lastGran = (l_numCurrAcc == (l_numAcc-1)) ? true : false;
+ bool l_firstGran = (l_numCurrAcc == 0) ? true : false;
+
+ // With ECC or ITAG the output length of a granule will become
+ // 9 bytes instead of 8, To align it we will merge 4 output granule
+ // before putting it in the Downstream FIFO i.e. 9*4 = 36Bytes
+ // which is 4Bytes aligned size.
+ // With Both ECC and ITag, the o/p length of a granule will become
+ // 10Bytes instead of 8, To align it we will merge 4 output granule
+ // before putting it in the Downstream FIFO i.e. 10*4 = 40bytes
+ // So in ADU Read case we will use the same buffer with 10Bytes
+ // offset to fill the 40bytes.
+
+ // Both Ecc and ITag Present = 40Bytes is the alignment length
+ /* D[00] D[01] D[02] D[03] D[04] D[05] D[06] D[07] -> 8 Data Bytes
+ * D[08-Itag] D[09-Ecc] D[0a] D[0b] D[0c] D[0d] D[0e] D[0f] -> 6D B
+ * D[10] D[11] D [12-Itag] D[13-Ecc] D[14] D[15] D[16] D[17]
+ * D[18] D[19] D[1a] D[1b] D[1c-Itag] D[1d-Ecc] D[1e] D[1f]
+ * D[20] D[21] D[22] D[23] D[24] D[25] D[26-Itag] D[27-Ecc]
+ */
+ // Only Ecc Present = 36 Bytes is the alignment length
+ /* D[00] D[01] D[02] D[03] D[04] D[05] D[06] D[07] -> 8 Data Bytes
+ * D[08-Ecc] D[09] D[0a] D[0b] D[0c] D[0d] D[0e] D[0f] -> 7D B
+ * D[10] D[11-Ecc] D [12] D[13] D[14] D[15] D[16] D[17]
+ * D[18] D[19] D[1a-Ecc] D[1b] D[1c] D[1d] D[1e] D[1f]
+ * D[20] D[21] D[22] D[23-Ecc]
+ */
+ // Only ITag Present = 36 Bytes is the alignment length
+ /* D[00] D[01] D[02] D[03] D[04] D[05] D[06] D[07] -> 8 Data Bytes
+ * D[08-Itag] D[09] D[0a] D[0b] D[0c] D[0d] D[0e] D[0f] -> 7D B
+ * D[10] D[11-Itag] D [12] D[13] D[14] D[15] D[16] D[17]
+ * D[18] D[19] D[1a-Itag] D[1b] D[1c] D[1d] D[1e] D[1f]
+ * D[20] D[21] D[22] D[23-Itag]
+ */
+ uint8_t l_bufIdx = 0;
+
+ // If this is putmem request, read input data from the upstream FIFO
+ if (!i_isFlagRead)
+ {
+ // l_sizeMultiplier * 4B Upstream FIFO = Granule size 128B
+ uint32_t l_len2dequeue = l_sizeMultiplier;
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue,
+ (uint32_t *)&l_dataFifo,
+ false);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+
+ // Insert the ECC if ECC Mode is set
+ if(l_isEccMode)
+ {
+ uint8_t l_eccPos = 8;
+ if(l_isItagMode)
+ {
+ l_eccPos = 9;
+ }
+ ((uint8_t*)&l_dataFifo)[l_eccPos] = i_hdr.eccByte;
+ }
+ }
+ else
+ {
+ //Adu Read Mode - with either ECC or ITag or Both
+ // Calculate the MODULUS
+ uint8_t l_mod = (l_numCurrAcc % 4);
+ if( (l_mod) && ((l_isEccMode) || (l_isItagMode)) )
+ {
+ // Default Init it for 1byte extra
+ l_bufIdx = (ADU_GRAN_SIZE_BYTES * l_mod) + l_mod;
+ if((l_isEccMode) && (l_isItagMode))
+ {
+ l_bufIdx = l_bufIdx + l_mod;
+ }
+ }
+ }
+
+ // Call ADU access HWP for ADU write/read request
+ l_fapiRc = p9_adu_access (
+ l_proc,
+ l_addr,
+ i_isFlagRead,
+ l_aduSetupFlags,
+ l_firstGran,
+ l_lastGran,
+ &(((uint8_t *)&(l_dataFifo))[l_bufIdx]));
+ // if p9_adu_access returns error
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" p9_adu_access Failed");
+ // Respond with HWP FFDC
+ l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION );
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+
+ // If this is a getmem request,
+ // need to push the data into the downstream FIFO
+ if (i_isFlagRead)
+ {
+ // Number of 4Bytes to put, to align with Granule Size
+ uint32_t l_len = l_sizeMultiplier; // l_len*4 = Granule Size
+
+ //Enter the below 'if' if ADU Read Mode with Either Ecc or ITag
+ //or both set. During non-aligned Transaction (but not the last)
+ //then set the len as zero so as to skip the unalign byte send,
+ //during next transaction when the data is aligned it will take
+ //care of sending all granules.
+ //If the below condition is not met then for ADU Read Mode will
+ //happen to write on DownStream FIFO for each granule.
+
+ //Calculate the MODULUS
+ uint8_t l_mod = (l_numCurrAcc % 4);
+ if((l_isEccMode) || (l_isItagMode))
+ {
+ if( (l_mod == 3) || (l_lastGran) )
+ {
+ l_len = calInterAduLenForUpFifo(l_mod,l_isItagMode,
+ l_isEccMode);
+ l_len = align4ByteWordLength(l_len);
+ }
+ else
+ {
+ // If it is not the last granule or on the 4th entry
+ // into the data buffer, need not send it to Upstream
+ // Fifo
+ l_len = 0;
+ }
+ }
+ if(l_len)
+ {
+ l_rc = sbeDownFifoEnq_mult (l_len, (uint32_t *)&l_dataFifo);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ }
+ }
+ l_granulesCompleted++;
+ l_numCurrAcc++;
+ } // End inner while loop
+
+ if ( (l_fapiRc != FAPI2_RC_SUCCESS) ||
+ (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) )
+ {
+ break;
+ }
+
+ l_addr += l_granuleSize * l_granulesCompleted;
+ } // End..while (l_granulesCompleted < l_lenCacheAligned);
+
+ // Now build and enqueue response into downstream FIFO
+ do
+ {
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ // If there was a HWP failure for putmem request,
+ // need to Flush out upstream FIFO, until EOT arrives
+ if (!i_isFlagRead)
+ {
+ l_rc = flushUpstreamFifo(l_fapiRc);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ }
+
+ // first enqueue the length of data actually written
+ uint32_t l_len = 1;
+ uint32_t l_respLen = sbeAduLenInUpStreamFifo(
+ l_granulesCompleted,
+ l_isItagMode,
+ l_isEccMode);
+
+ SBE_INFO(SBE_FUNC "Total length Pushed for ChipOp [%d]", l_respLen);
+ l_rc = sbeDownFifoEnq_mult ( l_len, &l_respLen );
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+
+ l_rc = sbeDsSendRespHdr( l_respHdr, l_ffdc);
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeMemAccess_Wrap Memory Access Wrapper function
+//
+// @param [in] i_isFlagRead Flag to indicate the memory Access Type
+// true : GetMem ChipOp
+// false : PutMem ChipOp
+//
+// @return RC from the method
+///////////////////////////////////////////////////////////////////////
+uint32_t sbeMemAccess_Wrap(const bool i_isFlagRead)
+{
+ #define SBE_FUNC " sbeMemAccess_Wrap "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ // Create an instance of Memory Access ChipOp structure
+ sbeMemAccessReqMsgHdr_t l_req = {0};
+
+ // Offload the common header from the Upstream FIFO
+ uint32_t l_len2dequeue = sizeof(l_req) / sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult(l_len2dequeue, (uint32_t *)&l_req, i_isFlagRead);
+
+ if(!l_rc)
+ {
+ // Calculate the PBA/ADU address from the given input
+ SBE_INFO(SBE_FUNC "Address Upper[0x%08X] Lower[0x%08X] Flags[0x%08X] "
+ "Length[0x%08X]", ((l_req.getAddr()>>32) & 0xFFFFFFFF),
+ (l_req.getAddr() & 0xFFFFFFFF), l_req.flags, l_req.len);
+
+ // PBA
+ bool l_isPBA = l_req.isPbaFlagSet();
+ if(l_isPBA)
+ {
+ l_rc = processPbaRequest(l_req, i_isFlagRead);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC "processPbaRequest failed");
+ }
+ }
+ // ADU
+ else
+ {
+ l_rc = processAduRequest(l_req, i_isFlagRead);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC "processAduRequest failed");
+ }
+ }
+ }
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbePutMem (uint8_t *i_pArg)
+{
+ return sbeMemAccess_Wrap (false);
+}
+
+/////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeGetMem (uint8_t *i_pArg)
+{
+ return sbeMemAccess_Wrap (true);
+}
+
diff --git a/src/sbefw/sbecmdmemaccess.H b/src/sbefw/sbecmdmemaccess.H
new file mode 100644
index 00000000..6a2449fc
--- /dev/null
+++ b/src/sbefw/sbecmdmemaccess.H
@@ -0,0 +1,54 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdmemaccess.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdmemaccess.H
+ *
+ * @brief This file contains the Interfaces for the Memory Access chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDMEMACCESS_H
+#define __SBEFW_SBECMDMEMACCESS_H
+
+#include <stdint.h>
+
+/**
+ * @brief sbeGetMem : Implements SBE Get Memory ChipOp
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetMem (uint8_t *i_pArg);
+
+/**
+ * @brief sbePutMem : Implements SBE Put Memory ChipOp
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbePutMem (uint8_t *i_pArg);
+
+#endif /* __SBEFW_SBECMDMEMACCESS_H */
diff --git a/src/sbefw/sbecmdparser.C b/src/sbefw/sbecmdparser.C
new file mode 100644
index 00000000..c22e67c7
--- /dev/null
+++ b/src/sbefw/sbecmdparser.C
@@ -0,0 +1,483 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdparser.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdparser.C
+ *
+ * @brief This file contains the SBE FIFO Commands
+ *
+ */
+
+#include "sbecmdparser.H"
+#include "sbecmdscomaccess.H"
+#include "sbecmdiplcontrol.H"
+#include "sbecmdgeneric.H"
+#include "sbecmdmemaccess.H"
+#include "sbecmdregaccess.H"
+#include "sbecmdcntrldmt.H"
+#include "sbecmdringaccess.H"
+#include "sbecmdsram.H"
+#include "sbecmdcntlinst.H"
+#include "sbecmdringaccess.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeHostMsg.H"
+#include "sbe_host_intf.H"
+#include "sbestates.H"
+#include "sberegaccess.H"
+
+// Declaration
+static const uint16_t HARDWARE_FENCED_STATE =
+ SBE_FENCE_AT_CONTINUOUS_IPL|SBE_FENCE_AT_QUIESCE|
+ SBE_FENCE_AT_DMT;
+
+static const uint16_t PUT_HARDWARE_FENCED_STATE =
+ HARDWARE_FENCED_STATE|SBE_FENCE_AT_MPIPL;
+
+////////////////////////////////////////////////////////////////
+// @brief g_sbeScomCmdArray
+////////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeScomCmdArray [] =
+{
+ {sbeGetScom,
+ SBE_CMD_GETSCOM,
+ HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+ {sbePutScom,
+ SBE_CMD_PUTSCOM,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+ {sbeModifyScom,
+ SBE_CMD_MODIFYSCOM,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+ {sbePutScomUnderMask,
+ SBE_CMD_PUTSCOM_MASK,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+ {sbeMultiScom,
+ SBE_CMD_MULTISCOM,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+};
+
+////////////////////////////////////////////////////////////////
+// @brief g_sbeIplControlCmdArray
+//
+////////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeIplControlCmdArray [] =
+{
+ {sbeHandleIstep,
+ SBE_CMD_EXECUTE_ISTEP,
+ PUT_HARDWARE_FENCED_STATE|SBE_FENCE_AT_RUNTIME|
+ SBE_FENCE_AT_DUMPING,
+ // This is allowed in FFDC Collect state
+ // TODO - Issue 157287 - Allow MPIIPL in Isteps state
+ },
+
+ {sbeContinueBoot,
+ SBE_CMD_CONTINUE_BOOT,
+ PUT_HARDWARE_FENCED_STATE|SBE_FENCE_AT_RUNTIME|
+ SBE_FENCE_AT_DUMPING|SBE_FENCE_AT_ISTEP,
+ // This is allowed only in FFDC Collect State in PLCK mode
+ },
+};
+
+////////////////////////////////////////////////////////////////
+// @brief g_sbeGenericCmdArray
+//
+////////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeGenericCmdArray [] =
+{
+ {sbeGetCapabilities,
+ SBE_CMD_GET_SBE_CAPABILITIES,
+ SBE_STATE_FFDC_COLLECT,
+ // Fence in FFDC Collect State, since it might over-write traces
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbeMemoryAccessCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeMemoryAccessCmdArray [] =
+{
+ {sbeGetMem,
+ SBE_CMD_GETMEM,
+ HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+
+ {sbePutMem,
+ SBE_CMD_PUTMEM,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+
+ {sbeGetOccSram,
+ SBE_CMD_GETSRAM_OCC,
+ HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+
+ {sbePutOccSram,
+ SBE_CMD_PUTSRAM_OCC,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbeInstructionCntlCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeInstructionCntlCmdArray[] =
+{
+ {sbeCntlInst,
+ SBE_CMD_CONTROL_INSTRUCTIONS,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbeRegAccessCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeRegAccessCmdArray [] =
+{
+ {sbeGetReg,
+ SBE_CMD_GETREG,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+
+ {sbePutReg,
+ SBE_CMD_PUTREG,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbeMpiplCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeMpiplCmdArray[] =
+{
+ {sbeEnterMpipl,
+ SBE_CMD_MPIPL_ENTER,
+ PUT_HARDWARE_FENCED_STATE|SBE_FENCE_AT_ISTEP|
+ SBE_FENCE_AT_DUMPING|SBE_FENCE_AT_ABORT,
+ // Allow Fspless system to enter MPIPL
+ // Honour MPIPL at FFDC Collect state
+ // Issue 157287
+ },
+
+ {sbeContinueMpipl,
+ SBE_CMD_MPIPL_CONTINUE,
+ HARDWARE_FENCED_STATE|SBE_FENCE_AT_ISTEP|
+ SBE_FENCE_AT_RUNTIME|SBE_FENCE_AT_DUMPING|
+ SBE_FENCE_AT_ABORT|SBE_FENCE_AT_FFDC_COLLECT,
+ // Only allowed State is MPIPL
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbeRingAccessCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeRingAccessCmdArray [] =
+{
+ {sbeGetRing,
+ SBE_CMD_GETRING,
+ SBE_FENCE_AT_CONTINUOUS_IPL,
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbeCoreStateControlCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeCoreStateControlCmdArray [] =
+{
+ {sbeControlDeadmanTimer,
+ SBE_PSU_CMD_CONTROL_DEADMAN,
+ SBE_FENCE_AT_CONTINUOUS_IPL|SBE_FENCE_AT_QUIESCE|
+ SBE_FENCE_AT_MPIPL|SBE_FENCE_AT_ISTEP|
+ SBE_FENCE_AT_DUMPING|SBE_FENCE_AT_ABORT|
+ SBE_FENCE_AT_FFDC_COLLECT,
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbePutRingFromImageCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbePutRingFromImageCmdArray [] =
+{
+ {sbePutRingFromImagePSU,
+ SBE_PSU_MSG_PUT_RING_FROM_IMAGE,
+ SBE_FENCE_AT_CONTINUOUS_IPL,
+ },
+};
+
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+uint8_t sbeGetCmdStructAttr (const uint8_t i_cmdClass,
+ sbeCmdStruct_t **o_ppCmd)
+{
+ #define SBE_FUNC " sbeGetCmdStructAttr "
+ uint8_t l_numCmds = 0;
+ *o_ppCmd = NULL;
+
+ switch(i_cmdClass)
+ {
+ // FIFO Commands
+ case SBE_CMD_CLASS_IPL_CONTROL:
+ // @TODO via RTC : 128655
+ // Use C++ style typecase
+ l_numCmds = sizeof(g_sbeIplControlCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeIplControlCmdArray;
+ break;
+ case SBE_CMD_CLASS_SCOM_ACCESS:
+ l_numCmds = sizeof(g_sbeScomCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeScomCmdArray;
+ break;
+ case SBE_CMD_CLASS_GENERIC_MESSAGE:
+ l_numCmds = sizeof(g_sbeGenericCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeGenericCmdArray;
+ break;
+
+ case SBE_CMD_CLASS_MEMORY_ACCESS:
+ l_numCmds = sizeof(g_sbeMemoryAccessCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeMemoryAccessCmdArray;
+ break;
+
+ case SBE_CMD_CLASS_INSTRUCTION_CONTROL:
+ l_numCmds = sizeof(g_sbeInstructionCntlCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeInstructionCntlCmdArray;
+ break;
+
+ case SBE_CMD_CLASS_REGISTER_ACCESS:
+ l_numCmds = sizeof(g_sbeRegAccessCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeRegAccessCmdArray;
+ break;
+
+ case SBE_CMD_CLASS_RING_ACCESS:
+ l_numCmds = sizeof(g_sbeRingAccessCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeRingAccessCmdArray;
+ break;
+
+ case SBE_CMD_CLASS_MPIPL_COMMANDS:
+ l_numCmds = sizeof(g_sbeMpiplCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeMpiplCmdArray;
+ break;
+
+ // PSU Commands
+ case SBE_PSU_CMD_CLASS_CORE_STATE:
+ l_numCmds = sizeof(g_sbeCoreStateControlCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeCoreStateControlCmdArray;
+ break;
+
+ case SBE_PSU_CMD_CLASS_RING_ACCESS:
+ l_numCmds = sizeof(g_sbePutRingFromImageCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbePutRingFromImageCmdArray;
+ break;
+
+ // This will grow with each class of chipOp in future
+ default:
+ break;
+ }
+ return l_numCmds;
+ #undef SBE_FUNC
+}
+
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+uint8_t sbeValidateCmdClass (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode)
+{
+ #define SBE_FUNC " sbeValidateCmdClass "
+ uint8_t l_rc = SBE_SEC_COMMAND_NOT_SUPPORTED;
+
+ SBE_INFO(SBE_FUNC"i_cmdClass[0x%02X], "
+ "i_cmdOpcode[0x%02X]", i_cmdClass, i_cmdOpcode);
+
+ do
+ {
+ uint8_t l_numCmds = 0;
+ sbeCmdStruct_t *l_pCmd = NULL;
+
+ l_numCmds = sbeGetCmdStructAttr (i_cmdClass, &l_pCmd);
+ if (!l_numCmds)
+ {
+ SBE_ERROR(SBE_FUNC"SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED "
+ "i_cmdClass[0x%02X], i_cmdOpcode[0x%02X]",
+ i_cmdClass, i_cmdOpcode);
+ // Command class not supported
+ l_rc = SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED;
+ break;
+ }
+
+ // @TODO via RTC : 128654
+ // Analyze on merging the validation functions into one
+ // and also on using loop vs switch case performance
+ for (uint8_t l_cnt = 0; l_cnt < l_numCmds; ++l_cnt, ++l_pCmd)
+ {
+ if (i_cmdOpcode == l_pCmd->cmd_opcode)
+ {
+ // Command found
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+ }
+ } while (false);
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+bool sbeIsCmdAllowedAtState (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode)
+{
+ #define SBE_FUNC " sbeIsCmdAllowedAtState "
+ uint8_t l_numCmds = 0;
+ sbeCmdStruct_t *l_pCmd = NULL;
+ bool l_ret = false;
+ l_numCmds = sbeGetCmdStructAttr (i_cmdClass, &l_pCmd);
+
+ for (uint8_t l_cnt = 0; l_cnt < l_numCmds; ++l_cnt, ++l_pCmd)
+ {
+ if (i_cmdOpcode == l_pCmd->cmd_opcode)
+ {
+ // Get the Present State
+ uint64_t l_state =
+ SbeRegAccess::theSbeRegAccess().getSbeState();
+ SBE_INFO(SBE_FUNC "SBE State [0x%08X] Fence State[0x%04X]",
+ (uint32_t)(l_state & 0xFFFFFFFF),l_pCmd->cmd_state_fence);
+
+ switch(l_state)
+ {
+ case SBE_STATE_QUIESCE:
+ case SBE_STATE_UNKNOWN:
+ case SBE_STATE_FAILURE:
+ // All operations are fenced here, return false
+ // Reset is the only Option available
+ break;
+
+ case SBE_STATE_FFDC_COLLECT:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_FFDC_COLLECT)? false:true);
+ break;
+ }
+
+ case SBE_STATE_IPLING:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_CONTINUOUS_IPL)? false:true);
+ break;
+ }
+
+ case SBE_STATE_ISTEP:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_ISTEP)? false:true);
+ break;
+ }
+
+ case SBE_STATE_RUNTIME:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_RUNTIME)? false:true);
+ break;
+ }
+
+ case SBE_STATE_DUMP:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_DUMPING)? false:true);
+ break;
+ }
+
+ case SBE_STATE_MPIPL:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_MPIPL)? false:true);
+ break;
+ }
+
+ case SBE_STATE_DMT:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_DMT)? false:true);
+ break;
+ }
+
+ case SBE_STATE_ABORT:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_ABORT)? false:true);
+ break;
+ }
+
+ default: break;
+ }
+ }
+ }
+ // For any other state, which is not handled above, return from here
+ return l_ret;
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+sbeCmdFunc_t sbeFindCmdFunc (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode)
+
+{
+ #define SBE_FUNC " sbeFindCmdFunc "
+ uint8_t l_numCmds = 0;
+ sbeCmdStruct_t *l_pCmd = NULL;
+
+ l_numCmds = sbeGetCmdStructAttr (i_cmdClass, &l_pCmd);
+
+ for (uint8_t l_cnt = 0; l_cnt < l_numCmds; ++l_cnt, ++l_pCmd)
+ {
+ if (i_cmdOpcode == l_pCmd->cmd_opcode)
+ {
+ break;
+ }
+ }
+
+ return l_pCmd ? (l_pCmd->cmd_func) : NULL;
+ #undef SBE_FUNC
+}
diff --git a/src/sbefw/sbecmdparser.H b/src/sbefw/sbecmdparser.H
new file mode 100644
index 00000000..d51995f2
--- /dev/null
+++ b/src/sbefw/sbecmdparser.H
@@ -0,0 +1,119 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdparser.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdparser.H
+ *
+ * @brief This file contains the SBE command details
+ *
+ */
+
+#ifndef __SBEFW_SBECMDPARSER_H
+#define __SBEFW_SBECMDPARSER_H
+
+#include <stdint.h>
+
+
+/**
+ * @brief SBE Command structure associating an opcode of a command
+ * to the processing function as well as the allowed states
+ *
+ */
+typedef uint32_t (*sbeChipOpFunc_t) (uint8_t *i_pArg);
+
+typedef struct {
+ sbeChipOpFunc_t cmd_func; /* Command function pointer */
+ uint8_t cmd_opcode; /* Command opcode */
+ uint16_t cmd_state_fence; /* Command fencing based on SBE state */
+} sbeCmdStruct_t;
+
+/**
+ * @brief SBE Command Fence attributes
+ *
+ */
+enum sbe_command_fence_attrs
+{
+ SBE_NO_FENCE = 0x0000, ///< Allow cmd in all states
+ SBE_FENCE_AT_ABORT = 0x0001, ///< Fence off at SBE Abort State
+ SBE_FENCE_AT_FFDC_COLLECT = 0x0002, ///< Fence off at FFDC Collect State
+ SBE_FENCE_AT_DUMPING = 0x0004, ///< Fence off at DUMPING State
+ SBE_FENCE_AT_MPIPL = 0x0010, ///< Fence off at MPIPL state
+ SBE_FENCE_AT_CONTINUOUS_IPL = 0x0040, ///< Fence off at cont IPL
+ SBE_FENCE_AT_ISTEP = 0x0080, ///< Fence off at istep state
+ SBE_FENCE_AT_RUNTIME = 0x0100, ///< Fence off at Runtime state
+ SBE_FENCE_AT_QUIESCE = 0x0200, ///< Fense off at Quiesce state
+ SBE_FENCE_AT_DMT = 0x0400, ///< Fense off at DMT state
+};
+
+/**
+ * @brief sbeValidateCmdClass Validates the command class and opcode
+ *
+ * @param[in] i_cmdClass Command class code
+ * @param[in] i_cmdOpcode Command opcode
+ *
+ * @return uint8_t return code
+ * SBE_SEC_OPERATION_SUCCESSFUL - Command found
+ * SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED
+ * SBE_SEC_COMMAND_NOT_SUPPORTED
+ */
+uint8_t sbeValidateCmdClass (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode);
+
+/**
+ * @brief sbeIsCmdAllowedAtState Validates if the command is allowed
+ * at the current SBE state
+ *
+ * @param[in] i_cmdClass Command class code
+ * @param[in] i_cmdOpcode Command opcode
+ *
+ * @return true command is allowed at the current state
+ * false command is not allowed at the current state
+ */
+bool sbeIsCmdAllowedAtState (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode);
+
+
+/**
+ * @brief sbeCmdFunc_t Typical signature for any SBE ChipOp back-end function
+ *
+ * @param[in] uint8_t *i_pArg Pointer to the argument to be passed to
+ * the chipOp function
+ *
+ * @return uint32_t Return code from the chipOp function
+ */
+typedef uint32_t ( *sbeCmdFunc_t ) (uint8_t *i_pArg);
+
+
+/**
+ * @brief sbeFindCmdFunc Finds the function corresponding to the command
+ *
+ * @param[in] i_cmdClass Command class code
+ * @param[in] i_cmdOpcode Command opcode
+ *
+ * @return sbeCmdFunc_t A pointer to the corresponding ChipOps function
+ */
+sbeCmdFunc_t sbeFindCmdFunc (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode);
+
+
+#endif // __SBEFW_SBECMDPARSER_H
diff --git a/src/sbefw/sbecmdprocessor.C b/src/sbefw/sbecmdprocessor.C
new file mode 100644
index 00000000..6a945b4a
--- /dev/null
+++ b/src/sbefw/sbecmdprocessor.C
@@ -0,0 +1,376 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdprocessor.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdprocessor.C
+ *
+ * @brief This file contains the SBE Command processing Thread Routines
+ *
+ */
+
+
+#include "sbeexeintf.H"
+#include "sbefifo.H"
+#include "sbecmdparser.H"
+#include "sbeirq.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "assert.h"
+#include "sbeFifoMsgUtils.H"
+#include "sbeerrorcodes.H"
+#include "sbeHostUtils.H"
+#include "sbeHostMsg.H"
+#include "sbecmdiplcontrol.H"
+#include "sberegaccess.H"
+#include "sbestates.H"
+#include "fapi2.H"
+
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+void sbeHandlePsuResponse (const uint32_t i_rc)
+{
+ #define SBE_FUNC " sbeHandlePsuResponse "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ do
+ {
+ uint8_t l_cnt = 0;
+ switch (i_rc)
+ {
+ case SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED:
+ case SBE_SEC_COMMAND_NOT_SUPPORTED:
+ case SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE:
+ // Caller sent an invalid Command class/opcode
+ // Set the Ack bit in SBE->PSU DB register
+ l_rc = sbeAcknowledgeHost();
+ if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ break;
+ }
+ // Set primary and secondary status
+ g_sbeSbe2PsuRespHdr.setStatus(SBE_PRI_INVALID_COMMAND, i_rc);
+
+ // Now Update SBE->PSU Mbx Reg4 with response
+ l_cnt = sizeof(g_sbeSbe2PsuRespHdr)/
+ sizeof(uint64_t);
+ l_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4,
+ reinterpret_cast<const uint64_t *>(
+ &g_sbeSbe2PsuRespHdr), l_cnt, true);
+ break;
+
+ case SBE_SEC_OS_FAILURE:
+ // Set primary and secondary status
+ g_sbeSbe2PsuRespHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ i_rc);
+
+ // Now Update SBE->PSU Mbx Reg4 with response
+ l_cnt = sizeof(g_sbeSbe2PsuRespHdr)/
+ sizeof(uint64_t);
+ l_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4,
+ reinterpret_cast<const uint64_t *>(
+ &g_sbeSbe2PsuRespHdr), l_cnt, true);
+ break;
+
+ case SBE_SEC_OPERATION_SUCCESSFUL:
+ // Services code successfully executed the chipOp.
+ SBE_INFO(SBE_FUNC"PSU ChipOp Done");
+ break;
+
+ default:
+ // The only possibility (as of now) to reach till this point
+ // is when there was a mbx register access (scom) failure
+ // happened. Going to return to the waiting loop.
+ break;
+ }
+ } while(false);
+
+ #undef SBE_FUNC
+}
+
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+void sbeHandleFifoResponse (const uint32_t i_rc)
+{
+ #define SBE_FUNC " sbeHandleFifoResponse "
+ SBE_ENTER(SBE_FUNC);
+
+ do
+ {
+ uint16_t l_primStatus = SBE_PRI_OPERATION_SUCCESSFUL;
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ // Handle FIFO reset case
+ if (i_rc == SBE_FIFO_RESET_RECEIVED)
+ {
+ break;
+ }
+
+ if ( (i_rc == SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA) ||
+ (i_rc == SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA) )
+ {
+ l_primStatus = SBE_PRI_INVALID_DATA;
+ }
+
+ uint32_t l_len2dequeue = 0;
+ uint32_t l_dist2StatusHdr = 0;
+ uint32_t l_sbeDownFifoRespBuf[4] = {0};
+ uint32_t l_secStatus = i_rc;
+
+ switch (i_rc)
+ {
+ case SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED:
+ case SBE_SEC_COMMAND_NOT_SUPPORTED:
+ case SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE:
+ // Caller sent Invalid Command
+
+ case SBE_SEC_OS_FAILURE:
+ // PK API Failures
+
+ // Flush out the upstream FIFO till EOT arrives
+ l_len2dequeue = 1;
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, NULL,
+ true, true);
+
+ if ( (l_rc == SBE_FIFO_RESET_RECEIVED) ||
+ (l_rc == SBE_SEC_FIFO_ACCESS_FAILURE) )
+ {
+ break;
+ }
+
+ if (l_rc)
+ {
+ l_secStatus = l_rc;
+ }
+
+ // Don't break here to force the flow through
+ // the next case to enqueue the response into
+ // the downstream FIFO
+
+ case SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA:
+ case SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA:
+ // EOT arrived prematurely in upstream FIFO
+ // or there were unexpected data in upstream FIFO
+
+ SBE_ERROR(SBE_FUNC"Operation failure, "
+ "l_primStatus[0x%08X], "
+ "l_secStatus[0x%08X]",
+ l_primStatus, l_secStatus);
+
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_dist2StatusHdr,
+ l_primStatus,
+ l_secStatus,
+ 0);
+ l_rc = sbeDownFifoEnq_mult (++l_dist2StatusHdr,
+ &l_sbeDownFifoRespBuf[0]);
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"sbeDownFifoEnq_mult failure,"
+ " l_rc[0x0%08X]", l_rc);
+ // not attempting to signal EOT
+ break;
+ }
+ // Follow through to signal EOT in downstream
+
+ case SBE_SEC_OPERATION_SUCCESSFUL: // Successful execution
+ // Signal EOT in Downstream FIFO
+ l_rc = sbeDownFifoSignalEot();
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"sbeDownFifoSignalEot failure,"
+ " l_rc[0x0%08X]", l_rc);
+ }
+ SBE_INFO(SBE_FUNC"ChipOp Done");
+ break;
+
+ default:
+ break;
+ }
+ } while (false);
+
+ #undef SBE_FUNC
+}
+
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+void sbeSyncCommandProcessor_routine(void *i_pArg)
+{
+ #define SBE_FUNC " sbeSyncCommandProcessor_routine "
+ SBE_ENTER(SBE_FUNC);
+
+ // Check the destination bit at the start
+ if(SbeRegAccess::theSbeRegAccess().isIstepMode())
+ {
+ // In this state, we need not take care of FFDC State, User may
+ // or may not fetch FFDC and may not issue sbeContinueboot
+ SBE_INFO(SBE_FUNC"Continuous IPL mode not set, will wait for "
+ "commands...");
+ (void)SbeRegAccess::theSbeRegAccess().
+ updateSbeState(SBE_STATE_ISTEP);
+ }
+ // If Istep mode is not set, it makes sense to check if we are directly
+ // in runtime.
+ else if(true == SbeRegAccess::theSbeRegAccess().isDestBitRuntime())
+ {
+ SBE_INFO(SBE_FUNC"Destination bit tells us to go to runtime");
+ (void)SbeRegAccess::theSbeRegAccess().
+ updateSbeState(SBE_STATE_RUNTIME);
+ }
+ // Now we can assume that we are in Continuous IPL mode, just check if
+ // FFDC needs to be collected before continuing with IPL
+ else if(true == SbeRegAccess::theSbeRegAccess().isCollectFFDCSet())
+ {
+ SBE_INFO(SBE_FUNC"FFDC Collect State - Waiting for FFDC to be picked");
+ (void)SbeRegAccess::theSbeRegAccess().
+ updateSbeState(SBE_STATE_FFDC_COLLECT);
+ }
+ else
+ {
+ SBE_INFO(SBE_FUNC"Continuous IPL Mode set... IPLing");
+ (void)SbeRegAccess::theSbeRegAccess().
+ updateSbeState(SBE_STATE_IPLING);
+ sbeDoContinuousIpl();
+ }
+
+ do
+ {
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ // Wait for new command processing
+ int l_rcPk = pk_semaphore_pend (
+ &g_sbeSemCmdProcess, PK_WAIT_FOREVER);
+
+ do
+ {
+ // Local Variables
+ uint8_t l_cmdClass = 0;
+ uint8_t l_cmdOpCode = 0;
+
+ // Reset the value of fapi2::current_err from previous value.
+ // This is required as none of procedure set this value in success
+ // case. So if we do not reset previous value, previous failure
+ // will impact new chipops also.
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Check on the Rx Thread Interrupt Bits for Interrupt Status
+ if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_PSU) )
+ {
+ l_rc = g_sbeSbe2PsuRespHdr.secStatus;
+ l_cmdClass = g_sbePsu2SbeCmdReqHdr.cmdClass;
+ l_cmdOpCode = g_sbePsu2SbeCmdReqHdr.command;
+ // Set this here, so that during response handling we know which
+ // interrupt we are processing, need not check for
+ // g_sbeIntrSource again
+ g_sbeIntrSource.setIntrSource(SBE_PROC_ROUTINE,
+ SBE_INTERFACE_PSU);
+ }
+ else if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_FIFO) )
+ {
+ l_rc = g_sbeCmdRespHdr.sec_status;
+ l_cmdClass = g_sbeFifoCmdHdr.cmdClass;
+ l_cmdOpCode = g_sbeFifoCmdHdr.command;
+ // Set this here, so that during response handling we know which
+ // interrupt we are processing, need not check for
+ // g_sbeIntrSource again
+ g_sbeIntrSource.setIntrSource(SBE_PROC_ROUTINE,
+ SBE_INTERFACE_FIFO);
+ }
+ else // SBE_INTERFACE_FIFO_RESET or SBE_INTERFACE_UNKNOWN
+ {
+ SBE_ERROR(SBE_FUNC"Unexpected interrupt communicated to the "
+ "processor thread. Interrupt source: 0x%02X 0x%02X",
+ g_sbeIntrSource.intrSource, g_sbeIntrSource.rxThrIntrSource);
+ assert(false);
+ break;
+ }
+
+ // PK API failure
+ if (l_rcPk != PK_OK)
+ {
+ SBE_ERROR(SBE_FUNC"pk_semaphore_pend failed, "
+ "l_rcPk=%d, g_sbeSemCmdRecv.count=%d",
+ l_rcPk, g_sbeSemCmdRecv.count);
+
+ // If it's a semphore_pend error then update the same to show
+ // internal failure
+ l_rc = SBE_SEC_OS_FAILURE;
+ }
+
+ // Check for error which Receiver thread might have set
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+
+ // Get the command function
+ sbeCmdFunc_t l_pFuncP = sbeFindCmdFunc (l_cmdClass, l_cmdOpCode);
+ assert( l_pFuncP )
+
+ // Call the ChipOp function
+ l_rc = l_pFuncP ((uint8_t *)i_pArg);
+
+ } while(false); // Inner do..while loop ends here
+
+ SBE_INFO (SBE_FUNC"New cmd arrived, g_sbeSemCmdProcess.count=%d "
+ "l_rc=[0x%04X]",
+ g_sbeSemCmdProcess.count, l_rc);
+
+ if ( g_sbeIntrSource.isSet(SBE_PROC_ROUTINE, SBE_INTERFACE_PSU) )
+ {
+ sbeHandlePsuResponse (l_rc);
+
+ // Enable Host interrupt
+ g_sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,SBE_INTERFACE_PSU);
+ pk_irq_enable(SBE_IRQ_HOST_PSU_INTR);
+ }
+ else if ( g_sbeIntrSource.isSet(SBE_PROC_ROUTINE, SBE_INTERFACE_FIFO) )
+ {
+ sbeHandleFifoResponse (l_rc);
+
+ // Enable the new data available interrupt
+ g_sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,SBE_INTERFACE_FIFO);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_RESET);
+ }
+ } while(true); // Thread always exists
+ SBE_EXIT(SBE_FUNC);
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+void sbeAsyncCommandProcessor_routine(void *arg)
+{
+ SBE_INFO("sbeAsyncCommandProcessor Thread started");
+
+ do
+ {
+ // @TODO RTC via : 130392
+ // Add infrastructure for host interface
+
+ } while(0);
+}
diff --git a/src/sbefw/sbecmdreceiver.C b/src/sbefw/sbecmdreceiver.C
new file mode 100644
index 00000000..50f24657
--- /dev/null
+++ b/src/sbefw/sbecmdreceiver.C
@@ -0,0 +1,325 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdreceiver.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdreceiver.C
+ *
+ * @brief This file contains the SBE Command Receiver Thread Routine
+ *
+ */
+
+
+#include "sbeexeintf.H"
+#include "sbefifo.H"
+#include "sbecmdparser.H"
+#include "sbeirq.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeFifoMsgUtils.H"
+#include "sbeerrorcodes.H"
+#include "sbeHostMsg.H"
+#include "sbeHostUtils.H"
+#include "sberegaccess.H"
+#include "sbeutil.H"
+
+sbeFifoCmdReqBuf_t g_sbeFifoCmdHdr;
+sbeCmdRespHdr_t g_sbeCmdRespHdr;
+sbePsu2SbeCmdReqHdr_t g_sbePsu2SbeCmdReqHdr;
+sbeSbe2PsuRespHdr_t g_sbeSbe2PsuRespHdr;
+sbeIntrHandle_t g_sbeIntrSource;
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+void sbeCommandReceiver_routine(void *i_pArg)
+{
+ #define SBE_FUNC " sbeCommandReceiver_routine "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ // Update SBE msgg reg to indicate that control loop
+ // is ready now to receive data on its interfaces
+ (void)SbeRegAccess::theSbeRegAccess().setSbeReady();
+
+ // Set Current State to First State i.e. Unknown
+ (void)SbeRegAccess::theSbeRegAccess().updateSbeState(SBE_STATE_UNKNOWN);
+
+ do
+ {
+ // @TODO via RTC: 128944
+ // Read Scratchpad
+ // Wait for new data in FIFO or FIFO reset interrupt or PSU interrupt
+ int l_rcPk = pk_semaphore_pend (&g_sbeSemCmdRecv, PK_WAIT_FOREVER);
+
+ do
+ {
+ uint8_t l_cmdClass = SBE_CMD_CLASS_UNKNOWN;
+ uint8_t l_command = 0xFF;
+
+ // pk API failure
+ if (l_rcPk != PK_OK)
+ {
+ break;
+ }
+
+ SBE_DEBUG(SBE_FUNC"Receiver unblocked");
+
+ // The responsibility of this thread is limited to reading off
+ // the FIFO or PSU interfaces to be able to decode the command
+ // class and the command opcode parameters.
+
+ // Received FIFO Reset interrupt
+ if ( g_sbeIntrSource.isSet(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_FIFO_RESET) )
+ {
+ SBE_ERROR(SBE_FUNC"FIFO reset received");
+ l_rc = SBE_FIFO_RESET_RECEIVED;
+ break;
+ }
+
+ // Received PSU interrupt
+ if ( g_sbeIntrSource.isSet(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_PSU) )
+ {
+ //Clear the Interrupt Source bit for PSU
+ g_sbeIntrSource.clearIntrSource(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_PSU);
+ g_sbeIntrSource.setIntrSource(SBE_RX_ROUTINE,
+ SBE_INTERFACE_PSU);
+ // First clear PSU->SBE DB bit 0
+ l_rc = sbeClearPsu2SbeDbBitX(SBE_PSU2SBE_DOORBELL_CLEAR_BIT0);
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Initialize the g_sbePsu2SbeCmdReqHdr
+ g_sbePsu2SbeCmdReqHdr.init();
+ // Read the request field from PSU->SBE Mbx Reg0
+ uint8_t l_cnt = sizeof(g_sbePsu2SbeCmdReqHdr)/sizeof(uint64_t);
+
+ l_rc = sbeReadPsu2SbeMbxReg(SBE_HOST_PSU_MBOX_REG0, l_cnt,
+ (uint64_t *)&g_sbePsu2SbeCmdReqHdr);
+
+ g_sbeSbe2PsuRespHdr.init();
+ l_cmdClass = g_sbePsu2SbeCmdReqHdr.cmdClass;
+ l_command = g_sbePsu2SbeCmdReqHdr.command;
+ } // end if loop for PSU interface chipOp handling
+
+ // Received FIFO New Data interrupt
+ else if ( g_sbeIntrSource.isSet(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_FIFO) )
+ {
+ //Clear the Interrupt Source bit for FIFO
+ g_sbeIntrSource.clearIntrSource(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_FIFO);
+ g_sbeIntrSource.setIntrSource(SBE_RX_ROUTINE,
+ SBE_INTERFACE_FIFO);
+
+ // This thread will attempt to unblock the command processor
+ // thread on the following scenarios:
+ // - Normal scenarios where SBE would need to respond to FSP
+ // via downstream FIFO. This includes SUCCESS cases as well
+ // as the cases for Invalid Data sequence or Command
+ // validation failure.
+ // - if there is a need to handle FIFO reset
+
+ // Accordingly, this will update g_sbeCmdRespHdr.prim_status
+ // and g_sbeCmdRespHdr.sec_status for command processor thread
+ // to handle them later in the sequence.
+
+ g_sbeFifoCmdHdr.cmdClass = SBE_CMD_CLASS_UNKNOWN;
+ g_sbeCmdRespHdr.init();
+ uint32_t len = sizeof(g_sbeFifoCmdHdr)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult ( len, (uint32_t *)&g_sbeFifoCmdHdr,
+ false );
+
+ // If FIFO reset is requested,
+ if (l_rc == SBE_FIFO_RESET_RECEIVED)
+ {
+ SBE_ERROR(SBE_FUNC"FIFO reset received");
+ break;
+ }
+
+ // If we received EOT out-of-sequence
+ if ( (l_rc == SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA) ||
+ (l_rc == SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA) )
+ {
+ SBE_ERROR(SBE_FUNC"sbeUpFifoDeq_mult failure, "
+ " l_rc=[0x%08X]", l_rc);
+ g_sbeCmdRespHdr.setStatus(SBE_PRI_INVALID_DATA, l_rc);
+
+ // Reassign l_rc to Success to Unblock command processor
+ // thread and let that take the necessary action.
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+
+ l_cmdClass = g_sbeFifoCmdHdr.cmdClass;
+ l_command = g_sbeFifoCmdHdr.command;
+ } // end else if loop for FIFO interface chipOp handling
+
+ // Any other FIFO access issue
+ if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+
+ // validate the command class and sub-class opcodes
+ l_rc = sbeValidateCmdClass (l_cmdClass, l_command) ;
+
+ if (l_rc)
+ {
+ // Command Validation failed;
+ SBE_ERROR(SBE_FUNC"Command validation failed");
+ if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_PSU) )
+ {
+ g_sbeSbe2PsuRespHdr.setStatus(SBE_PRI_INVALID_COMMAND,l_rc);
+ }
+ else if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_FIFO) )
+ {
+ g_sbeCmdRespHdr.setStatus(SBE_PRI_INVALID_COMMAND, l_rc);
+ }
+
+ // Reassign l_rc to Success to Unblock command processor
+ // thread and let that take the necessary action.
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+
+ // Need to return from receiver thread itself for fenced rejection
+ // of command, but there might be contention on the response sent
+ // over FIFO/Mailbox usage.
+ if(false == sbeIsCmdAllowedAtState(l_cmdClass, l_command))
+ {
+ // This command is not allowed in this state
+ SBE_ERROR("Chip-Op CmdClass[0x%02X] Cmd[0x%02X] not allowed in "
+ "State - [0x%04X] ",l_cmdClass,l_command,
+ SbeRegAccess::theSbeRegAccess().getSbeState());
+
+ if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE, SBE_INTERFACE_PSU) )
+ {
+ g_sbeSbe2PsuRespHdr.setStatus(SBE_PRI_INVALID_COMMAND,
+ SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE);
+ }
+ else if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_FIFO) )
+ {
+ g_sbeCmdRespHdr.setStatus(SBE_PRI_INVALID_COMMAND,
+ SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE);
+ }
+
+ l_rc = SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE;
+ break;
+ }
+
+ } while (false); // Inner do..while ends
+
+ // If there was a FIFO reset request,
+ if (l_rc == SBE_FIFO_RESET_RECEIVED)
+ {
+ // Perform FIFO Reset
+ uint32_t l_rc = sbeUpFifoPerformReset();
+ if (l_rc)
+ {
+ // Perform FIFO Reset failed
+ SBE_ERROR(SBE_FUNC"Perform FIFO Reset failed, "
+ "l_rc=[0x%08X]", l_rc);
+ // Collect FFDC?
+ }
+
+ if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE, SBE_INTERFACE_FIFO) )
+ {
+ g_sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,
+ SBE_INTERFACE_FIFO);
+ }
+
+ if ( g_sbeIntrSource.isSet(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_FIFO_RESET) )
+ {
+ g_sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,
+ SBE_INTERFACE_FIFO_RESET);
+ }
+
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_RESET);
+ continue;
+ } // FIFO reset handling ends
+
+ // Unblock the command processor thread
+ // if we could dequeue the header successfully,
+ if ((l_rcPk == PK_OK) && (l_rc == SBE_SEC_OPERATION_SUCCESSFUL))
+ {
+ l_rcPk = pk_semaphore_post(&g_sbeSemCmdProcess);
+ }
+
+ // Handle Cmd not in a valid state here
+
+ if ((l_rcPk != PK_OK) || (l_rc != SBE_SEC_OPERATION_SUCCESSFUL))
+ {
+ if(l_rc != SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE)
+ {
+ // It's likely a code bug or PK failure,
+ // or any other PSU/FIFO access (scom) failure.
+
+ // @TODO via RTC : 129166
+ // Review if we need to add ASSERT here
+
+ // Add Error trace, collect FFDC and
+ // continue wait for the next interrupt
+ SBE_ERROR(SBE_FUNC"Unexpected failure, "
+ "l_rcPk=[%d], g_sbeSemCmdProcess.count=[%d], l_rc=[%d]",
+ l_rcPk, g_sbeSemCmdProcess.count, l_rc);
+ }
+ if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_PSU) )
+ {
+ if(l_rc == SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE)
+ {
+ sbeHandlePsuResponse(l_rc);
+ }
+ g_sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,
+ SBE_INTERFACE_PSU);
+ pk_irq_enable(SBE_IRQ_HOST_PSU_INTR);
+ }
+ else if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_FIFO) )
+ {
+ if(l_rc == SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE)
+ {
+ sbeHandleFifoResponse(l_rc);
+ }
+ g_sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,
+ SBE_INTERFACE_FIFO);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+ }
+ continue;
+ }
+
+ SBE_DEBUG(SBE_FUNC"Posted g_sbeSemCmdProcess, "
+ "g_sbeSemCmdProcess.count=[%d]", g_sbeSemCmdProcess.count);
+
+ } while (true); // thread always exists
+ #undef SBE_FUNC
+}
diff --git a/src/sbefw/sbecmdregaccess.C b/src/sbefw/sbecmdregaccess.C
new file mode 100644
index 00000000..d4023f73
--- /dev/null
+++ b/src/sbefw/sbecmdregaccess.C
@@ -0,0 +1,274 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdregaccess.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdregaccess.C
+ *
+ * @brief This file contains the SBE Reg Access chipOps
+ *
+ */
+
+#include "sbecmdregaccess.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbeFifoMsgUtils.H"
+#include "p9_ram_core.H"
+
+using namespace fapi2;
+
+Enum_RegType getRegType( const sbeRegAccessMsgHdr_t &regReq)
+{
+ Enum_RegType type = REG_GPR;
+ switch( regReq.regType )
+ {
+ case SBE_REG_ACCESS_SPR:
+ type = REG_SPR;
+ break;
+
+ case SBE_REG_ACCESS_FPR:
+ type = REG_FPR;
+ break;
+ }
+ return type;
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeGetReg(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeGetReg "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbeRegAccessMsgHdr_t regReqMsg;
+ uint32_t reqData[SBE_MAX_REG_ACCESS_REGS];
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeResponseFfdc_t ffdc;
+ ReturnCode fapiRc;
+
+ do
+ {
+ // Get the reg access header
+ uint32_t len = sizeof(sbeRegAccessMsgHdr_t)/sizeof(uint32_t);
+ rc = sbeUpFifoDeq_mult (len, (uint32_t *)&regReqMsg, false);
+
+ // If FIFO access failure
+ if (rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+ if( false == regReqMsg.isValidRequest() )
+ {
+ SBE_ERROR(SBE_FUNC" Invalid request. core: 0x%02x threadNr:0x%x"
+ " regType:0x%01x numRegs:0x%02x", regReqMsg.coreChiplet,
+ regReqMsg.threadNr, regReqMsg.regType, regReqMsg.numRegs);
+
+ respHdr.setStatus( SBE_PRI_INVALID_DATA,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ break;
+ }
+
+ len = regReqMsg.numRegs;
+ rc = sbeUpFifoDeq_mult (len, reqData, true);
+ if (rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ uint8_t core = regReqMsg.coreChiplet;
+ RamCore ramCore( plat_getTargetHandleByChipletNumber
+ <fapi2::TARGET_TYPE_CORE>(core),
+ regReqMsg.threadNr );
+
+ fapiRc = ramCore.ram_setup();
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" ram_setup failed. threadNr:0x%x"
+ "chipletId:0x%02x", regReqMsg.threadNr, core);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+
+ fapi2::buffer<uint64_t> data64;
+ uint64_t respData = 0;
+ for( uint32_t regIdx = 0; regIdx < regReqMsg.numRegs; regIdx++ )
+ {
+ fapiRc = ramCore.get_reg( getRegType(regReqMsg), reqData[regIdx],
+ &data64, true );
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" get_reg failed. threadNr:0x%x"
+ "chipletId:0x%02x, regNr:%u regType:%u ",
+ regReqMsg.threadNr, core, reqData[regIdx],
+ regReqMsg.regType);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+ respData = data64;
+ // Now enqueue into the downstream FIFO
+ len = sizeof( respData )/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult (len, ( uint32_t *)&respData);
+ if (rc)
+ {
+ break;
+ }
+ }
+ // HWP team does not care about cleanup for failure case.
+ // So call cleaup only for success case.
+ if( ffdc.getRc() )
+ {
+ break;
+ }
+ fapiRc = ramCore.ram_cleanup();
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" ram_cleanup failed. threadNr:0x%x"
+ "chipletId:0x%02x", regReqMsg.threadNr, core);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ }
+ }while(false);
+
+ if ( SBE_SEC_OPERATION_SUCCESSFUL == rc )
+ {
+ rc = sbeDsSendRespHdr( respHdr, ffdc);
+ }
+
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbePutReg(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbePutReg "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbeRegAccessMsgHdr_t regReqMsg;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeResponseFfdc_t ffdc;
+ ReturnCode fapiRc;
+
+ do
+ {
+ // Get the reg access header
+ uint32_t len = sizeof(sbeRegAccessMsgHdr_t)/sizeof(uint32_t);
+ rc = sbeUpFifoDeq_mult (len, (uint32_t *)&regReqMsg, false);
+
+ // If FIFO access failure
+ if (rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+ if( false == regReqMsg.isValidRequest() )
+ {
+ SBE_ERROR(SBE_FUNC" Invalid request. threadNr:0x%x"
+ " regType:0x%02x numRegs:0x%02x", regReqMsg.threadNr,
+ regReqMsg.regType, regReqMsg.numRegs);
+ respHdr.setStatus( SBE_PRI_INVALID_DATA,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ break;
+ }
+
+ sbeRegAccessPackage_t regPkg[SBE_MAX_REG_ACCESS_REGS];
+ len = (sizeof(sbeRegAccessPackage_t)/sizeof(uint32_t)) *
+ regReqMsg.numRegs;
+ rc = sbeUpFifoDeq_mult (len, (uint32_t *) regPkg,true );
+ if (rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ uint8_t core = regReqMsg.coreChiplet;
+ RamCore ramCore( plat_getTargetHandleByChipletNumber
+ <fapi2::TARGET_TYPE_CORE>(core),
+ regReqMsg.threadNr );
+
+ fapiRc = ramCore.ram_setup();
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" ram_setup failed. threadNr:0x%x"
+ "chipletId:0x%02x", regReqMsg.threadNr, core);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+
+ fapi2::buffer<uint64_t> data64;
+ for( uint32_t regIdx = 0; regIdx < regReqMsg.numRegs; regIdx++ )
+ {
+ data64 = regPkg[regIdx].getData();
+ fapiRc = ramCore.put_reg( getRegType(regReqMsg),
+ regPkg[regIdx].regNr,
+ &data64, true );
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" get_reg failed. threadNr:0x%x"
+ "chipletId:0x%02x, regNr:%u regType:%u ",
+ regReqMsg.threadNr, core, regPkg[regIdx].regNr,
+ regReqMsg.regType);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+ }
+ // HWP team does not care about cleanup for failure case.
+ // So call cleaup only for success case.
+ if( ffdc.getRc() )
+ {
+ break;
+ }
+ fapiRc = ramCore.ram_cleanup();
+ if( fapiRc )
+ {
+ SBE_ERROR(SBE_FUNC" ram_cleanup failed. threadNr:0x%x"
+ " chipletId:0x%02x", regReqMsg.threadNr, core);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ }
+
+ }while(false);
+
+ if ( SBE_SEC_OPERATION_SUCCESSFUL == rc )
+ {
+ rc = sbeDsSendRespHdr( respHdr, ffdc);
+ }
+
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+
diff --git a/src/sbefw/sbecmdregaccess.H b/src/sbefw/sbecmdregaccess.H
new file mode 100644
index 00000000..01199816
--- /dev/null
+++ b/src/sbefw/sbecmdregaccess.H
@@ -0,0 +1,56 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdregaccess.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdregaccess.H
+ *
+ * @brief This file contains the Interfaces for the SCOM Access chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDREGACCESS_H
+#define __SBEFW_SBECMDREGACCESS_H
+
+#include <stdint.h>
+
+/**
+ * @brief sbeGetRegs : Get the reg data
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetReg(uint8_t *i_pArg);
+
+
+/**
+ * @brief sbePutRegs : Put the reg data
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbePutReg(uint8_t *i_pArg);
+
+
+#endif /* __SBEFW_SBECMDREGACCESS_H */
diff --git a/src/sbefw/sbecmdringaccess.C b/src/sbefw/sbecmdringaccess.C
new file mode 100644
index 00000000..3fdc8f7e
--- /dev/null
+++ b/src/sbefw/sbecmdringaccess.C
@@ -0,0 +1,305 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdringaccess.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdringaccess.C
+ *
+ * @brief This file contains the SBE Ring Access chipOps
+ *
+ */
+
+#include "sbecmdringaccess.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbeHostMsg.H"
+#include "sbeHostUtils.H"
+#include "sbeFifoMsgUtils.H"
+#include "sbeutil.H"
+#include "fapi2.H"
+#include "plat_hw_access.H"
+
+using namespace fapi2;
+
+static const uint32_t SIZE_OF_LENGTH_INWORDS = 1;
+static const uint32_t NUM_WORDS_PER_GRANULE = 2;
+static const uint32_t GETRING_GRANULE_SIZE_IN_BITS = 64;
+
+/*@brief - Map sbe ring access modes to fapi ring access modes
+ *
+ * @param[in] - i_ringMode - sbe ring access mode
+ *
+ * @return - l_fapiRingMode - fapi ring mode
+ */
+uint16_t sbeToFapiRingMode(uint16_t i_ringMode)
+{
+ uint16_t l_fapiRingMode = RING_MODE_HEADER_CHECK;
+
+ if(i_ringMode & SBE_RING_MODE_SET_PULSE_NO_OPCG_COND)
+ {
+ l_fapiRingMode |= RING_MODE_SET_PULSE_NO_OPCG_COND;
+ }
+ if(i_ringMode & SBE_RING_MODE_NO_HEADER_CHECK)
+ {
+ l_fapiRingMode |= RING_MODE_NO_HEADER_CHECK;
+ }
+ if(i_ringMode & SBE_RING_MODE_SET_PULSE_NSL)
+ {
+ l_fapiRingMode |= RING_MODE_SET_PULSE_NSL;
+ }
+ if(i_ringMode & SBE_RING_MODE_SET_PULSE_SL)
+ {
+ l_fapiRingMode |= RING_MODE_SET_PULSE_SL;
+ }
+ if(i_ringMode & SBE_RING_MODE_SET_PULSE_ALL)
+ {
+ l_fapiRingMode |= RING_MODE_SET_PULSE_ALL;
+ }
+ return l_fapiRingMode;
+}
+
+/*@brief - create fapi target handle for the target type
+ *
+ * @param[in] - i_taretType - sbe ring target type
+ * @param[in] - i_chipletId - chiplet id
+ * @param[out] - o_tgtHndl - fapi target handle
+ *
+ * @return - true - on success
+ * false - on failure
+ */
+bool sbeGetFapiTargetHandle(uint16_t i_targetType,
+ uint16_t i_chipletId,
+ fapi2::plat_target_handle_t &o_tgtHndl)
+{
+ bool l_rc = true;
+ o_tgtHndl = NULL;
+ switch(i_targetType)
+ {
+ case TARGET_EX:
+ o_tgtHndl = plat_getTargetHandleByChipletNumber
+ <fapi2::TARGET_TYPE_EX>(i_chipletId);
+ break;
+ case TARGET_PERV:
+ o_tgtHndl = plat_getTargetHandleByChipletNumber
+ <fapi2::TARGET_TYPE_PERV>(i_chipletId);
+ break;
+ case TARGET_PROC_CHIP:
+ o_tgtHndl = plat_getChipTarget().get();
+ break;
+ default:
+ l_rc = false;
+ break;
+ }
+ return l_rc;
+}
+
+uint32_t sbePutRingFromImagePSU (uint8_t *i_pArg)
+{
+#define SBE_FUNC " sbePutRingFromImagePSU "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t l_fapiRc = FAPI2_RC_SUCCESS;
+ sbePSUPutRingCMD_t l_cmd = {0};
+ do
+ {
+ // Fetch Ring ID, Ring mode and pervasive chiplet id from the message
+ // and also send Ack to Host via SBE_SBE2PSU_DOORBELL_SET_BIT1
+ l_rc = sbeReadPsu2SbeMbxReg(SBE_HOST_PSU_MBOX_REG1,
+ (sizeof(l_cmd)/sizeof(uint64_t)),
+ (uint64_t*)&l_cmd,
+ true);
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC "Failed to extract SBE_HOST_PSU_MBOX_REG1 and "
+ "SBE_HOST_PSU_MBOX_REG2");
+ break;
+ }
+
+ // Construct a Target from Chiplet ID and Target Type
+ fapi2::plat_target_handle_t l_tgtHndl = {0};
+ if(!sbeGetFapiTargetHandle(l_cmd.TargetType, l_cmd.ChipletID,
+ l_tgtHndl))
+ {
+ SBE_ERROR(SBE_FUNC "Invalid target type [0x%04x]",
+ (uint16_t)l_cmd.TargetType);
+ g_sbeSbe2PsuRespHdr.setStatus(SBE_PRI_INVALID_DATA,
+ SBE_SEC_INVALID_TARGET_TYPE_PASSED);
+ break;
+ }
+ fapi2::Target<TARGET_TYPE_ALL> l_Tgt(l_tgtHndl);
+
+ // Initialize with HEADER CHECK mode
+ uint16_t l_ringMode = sbeToFapiRingMode(l_cmd.RingMode);
+
+ l_fapiRc = (uint32_t)putRing(l_Tgt, (RingID)l_cmd.RingID,
+ (RingMode)l_ringMode);
+ if(l_fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "putRing HWP failure - "
+ "MSG - Target Type [0x%04x] Ring ID [0x%04x]"
+ " Ring Mode [0x%04x] Chiplet ID [0x%04x]",
+ l_cmd.TargetType,
+ l_cmd.RingID,
+ l_cmd.RingMode,
+ l_cmd.ChipletID);
+ break;
+ }
+ }while(0); // End of do-while
+
+ // Send the response
+ sbePSUSendResponse(g_sbeSbe2PsuRespHdr, l_fapiRc, l_rc);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+#undef SBE_FUNC
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeGetRing(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeGetRing "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbeGetRingAccessMsgHdr_t l_reqMsg;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeResponseFfdc_t l_ffdc;
+ ReturnCode l_fapiRc;
+ uint32_t l_len = 0;
+ uint32_t l_bitSentCnt = 0;
+
+ do
+ {
+ // Get the ring access header
+ l_len = sizeof(sbeGetRingAccessMsgHdr_t)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len, (uint32_t *)&l_reqMsg); // EOT fetch
+
+ // If FIFO access failure
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+
+ SBE_INFO(SBE_FUNC "Ring Address 0x%08X User Ring Mode 0x%04X "
+ "Length in Bits 0x%08X",
+ l_reqMsg.ringAddr, l_reqMsg.ringMode, l_reqMsg.ringLenInBits);
+
+ uint16_t l_ringMode = sbeToFapiRingMode(l_reqMsg.ringMode);
+
+ // Call getRing_setup - loads the scan region data for the given ring
+ // address and updates the check word data
+ l_fapiRc = fapi2::getRing_setup(l_reqMsg.ringAddr,
+ (fapi2::RingMode)l_ringMode);
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" getRing_setup failed. RingAddress:0x%08X "
+ "RingMode:0x%04x", l_reqMsg.ringAddr, l_ringMode);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+ // Calculate the iteration length
+ uint32_t l_loopCnt =
+ (l_reqMsg.ringLenInBits / GETRING_GRANULE_SIZE_IN_BITS);
+ // Check for modulus - remainder
+ uint8_t l_mod = (l_reqMsg.ringLenInBits % GETRING_GRANULE_SIZE_IN_BITS);
+ if(l_mod)
+ {
+ ++l_loopCnt;
+ }
+
+ // fix for the alignment issue
+ uint32_t l_buf[NUM_WORDS_PER_GRANULE]__attribute__ ((aligned (8))) ={0};
+ uint32_t l_bitShift = 0;
+ l_len = NUM_WORDS_PER_GRANULE;
+
+ // Fetch the ring data in bits, each iteration will give you 64bits
+ for(uint32_t l_cnt=0; l_cnt < l_loopCnt; l_cnt++)
+ {
+ if((l_cnt == (l_loopCnt-1)) && (l_mod))
+ {
+ l_bitShift = l_mod;
+ }
+ else
+ {
+ l_bitShift = GETRING_GRANULE_SIZE_IN_BITS;
+ }
+ // Call getRing_granule_data - read the 64 bit data from the HW
+ l_fapiRc = getRing_granule_data((uint32_t)(l_reqMsg.ringAddr),
+ (uint64_t*)&l_buf,
+ l_bitShift);
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" getRing_granule_data failed. "
+ "RingAddress:0x%08X RingMode:0x%04x",
+ l_reqMsg.ringAddr, l_ringMode);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+
+ // Send it to DS Fifo
+ // If this is the last iteration in the loop, let the full 64bit
+ // go, even for 1bit of remaining length. The length passed to
+ // the user will take care of actual number of bits.
+ l_rc = sbeDownFifoEnq_mult (l_len, (uint32_t *)&l_buf);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ l_bitSentCnt = l_bitSentCnt + l_bitShift;
+ }
+ if ( (l_fapiRc == FAPI2_RC_SUCCESS) &&
+ (l_rc == SBE_SEC_OPERATION_SUCCESSFUL) )
+ {
+ // Call getRing_verifyAndcleanup - verify the check word data is
+ // matching or not and will clean up the scan region data
+ l_fapiRc = getRing_verifyAndcleanup((uint32_t)(l_reqMsg.ringAddr),
+ (fapi2::RingMode)l_ringMode);
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" getRing_verifyAndcleanup failed. "
+ "RingAddress:0x%08X RingMode:0x%04x",
+ l_reqMsg.ringAddr, l_ringMode);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ }
+ }
+ }while(false);
+
+ // Now build and enqueue response into downstream FIFO
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ if ( SBE_SEC_OPERATION_SUCCESSFUL == l_rc )
+ {
+ l_len = SIZE_OF_LENGTH_INWORDS;
+ l_rc = sbeDownFifoEnq_mult (l_len, &(l_bitSentCnt));
+ if(SBE_SEC_OPERATION_SUCCESSFUL == l_rc)
+ {
+ l_rc = sbeDsSendRespHdr( respHdr, l_ffdc);
+ }
+ }
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+#undef SBE_FUNC
+}
+
diff --git a/src/sbefw/sbecmdringaccess.H b/src/sbefw/sbecmdringaccess.H
new file mode 100644
index 00000000..d2163646
--- /dev/null
+++ b/src/sbefw/sbecmdringaccess.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdringaccess.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdringaccess.H
+ *
+ * @brief This file contains the Interfaces for the RING Access chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDRINGACCESS_H
+#define __SBEFW_SBECMDRINGACCESS_H
+
+#include <stdint.h>
+
+typedef struct
+{
+ uint64_t TargetType:16;
+ uint64_t ChipletID:16;
+ uint64_t RingID:16;
+ uint64_t RingMode:16;
+} sbePSUPutRingCMD_t;
+
+/**
+ * @brief Put Ring From Image Command (0xD301)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return RC from the PSU access utility
+ */
+uint32_t sbePutRingFromImagePSU(uint8_t *i_pArg);
+
+/**
+ * @brief sbeGetRing : Get the ring data
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetRing(uint8_t *i_pArg);
+
+
+#endif /* __SBEFW_SBECMDRINGACCESS_H */
diff --git a/src/sbefw/sbecmdscomaccess.C b/src/sbefw/sbecmdscomaccess.C
new file mode 100644
index 00000000..e99ce89f
--- /dev/null
+++ b/src/sbefw/sbecmdscomaccess.C
@@ -0,0 +1,495 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdscomaccess.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdscomaccess.C
+ *
+ * @brief This file contains the SBE SCOM Access chipOps
+ *
+ */
+
+#include "sbecmdscomaccess.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbescom.H"
+#include "sbeutil.H"
+#include "sbeFifoMsgUtils.H"
+
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeGetScom (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeGetScom "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbeGetScomReqMsg_t l_getScomReqMsg;
+
+ do
+ {
+ uint16_t l_primStatus = g_sbeCmdRespHdr.prim_status;
+ uint16_t l_secStatus = g_sbeCmdRespHdr.sec_status ;
+
+ // Will attempt to dequeue two entries for
+ // the scom addresses plus the expected
+ // EOT entry at the end
+
+ uint32_t l_len2dequeue = sizeof(l_getScomReqMsg)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, (uint32_t *)&l_getScomReqMsg);
+
+ // If FIFO access failure
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ uint32_t l_sbeDownFifoRespBuf[6] = {0};
+ uint32_t l_pcbpibStatus = SBE_PCB_PIB_ERROR_NONE;
+ uint32_t l_len2enqueue = 0;
+ uint32_t l_index = 0;
+
+ uint64_t l_addr = ( (uint64_t)l_getScomReqMsg.hiAddr << 32) |
+ l_getScomReqMsg.lowAddr;
+ uint64_t l_scomData = 0;
+ SBE_DEBUG(SBE_FUNC"scomAddr[0x%08X%08X]",
+ l_getScomReqMsg.hiAddr, l_getScomReqMsg.lowAddr);
+ l_rc = checkIndirectAndDoScom(true, l_addr,
+ l_scomData, l_pcbpibStatus);
+
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) // scom failed
+ {
+ SBE_ERROR(SBE_FUNC"getscom failed, l_pcbpibStatus[0x%08X], "
+ "scomAddr[0x%08X%08X]", l_pcbpibStatus,
+ l_getScomReqMsg.hiAddr, l_getScomReqMsg.lowAddr);
+ l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE;
+ l_secStatus = l_rc;
+ }
+ else // successful scom
+ {
+ SBE_DEBUG(SBE_FUNC"getscom succeeds, l_scomData[0x%016X]",
+ l_scomData);
+
+ l_sbeDownFifoRespBuf[0] = (uint32_t)(l_scomData>>32);
+ l_sbeDownFifoRespBuf[1] = (uint32_t)(l_scomData);
+
+ // Push the data into downstream FIFO
+ l_len2enqueue = 2;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue,
+ &l_sbeDownFifoRespBuf[0]);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+ l_index = 2;
+ } // end successful scom
+
+ // Build the response header packet
+
+ uint32_t l_curIndex = l_index ;
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_curIndex,
+ l_primStatus,
+ l_secStatus,
+ l_pcbpibStatus,
+ l_index);
+
+ // Now enqueue into the downstream FIFO
+ l_len2enqueue = ++l_curIndex - l_index;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue,
+ &l_sbeDownFifoRespBuf[l_index]);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbePutScom (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbePutScom "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbePutScomReqMsg_t l_putScomReqMsg;
+
+ do
+ {
+ uint16_t l_primStatus = g_sbeCmdRespHdr.prim_status;
+ uint16_t l_secStatus = g_sbeCmdRespHdr.sec_status ;
+
+ // Will attempt to dequeue four entries for
+ // the scom address (two entries) and the
+ // corresponding data (two entries) plus
+ // the expected EOT entry at the end
+
+ uint32_t l_len2dequeue = sizeof(l_putScomReqMsg)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, (uint32_t *)&l_putScomReqMsg);
+
+ // If FIFO access failure
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ uint64_t l_scomData = 0;
+ uint32_t l_sbeDownFifoRespBuf[4] = {0};
+ uint32_t l_pcbpibStatus = SBE_PCB_PIB_ERROR_NONE;
+ uint32_t l_len2enqueue = 0;
+ // successfully dequeued two entries for
+ // scom address followed by the EOT entry
+
+ // Data entry 0 : Scom Register Address (0..31)
+ // Data entry 1 : Scom Register Address (32..63)
+ // Data entry 2 : Scom Register Data (0..31)
+ // Data entry 3 : Scom Register Data (32..63)
+ // For Direct SCOM, will ignore entry 0
+
+ l_scomData = l_putScomReqMsg.getScomData();
+
+ uint64_t l_addr = ( (uint64_t) l_putScomReqMsg.hiAddr << 32) |
+ l_putScomReqMsg.lowAddr;
+ SBE_DEBUG(SBE_FUNC"scomAddr[0x%08X%08X]",
+ l_putScomReqMsg.hiAddr, l_putScomReqMsg.lowAddr);
+ l_rc = checkIndirectAndDoScom(false, l_addr,
+ l_scomData, l_pcbpibStatus);
+
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) // scom failed
+ {
+ SBE_ERROR(SBE_FUNC"putscom failed, l_pcbpibStatus[0x%08X]",
+ l_pcbpibStatus);
+ SBE_ERROR(SBE_FUNC"putscom failure data, "
+ "scomAddr[0x%08X%08X], "
+ "scomData[0x%08X%08X]",
+ l_putScomReqMsg.hiAddr,
+ l_putScomReqMsg.lowAddr,
+ SBE::higher32BWord(l_scomData),
+ SBE::lower32BWord(l_scomData));
+ l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE;
+ l_secStatus = l_rc;
+ }
+
+ // Build the response header packet
+
+ uint32_t l_curIndex = 0;
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_curIndex,
+ l_primStatus,
+ l_secStatus,
+ l_pcbpibStatus);
+
+ // Now enqueue into the downstream FIFO
+ l_len2enqueue = ++l_curIndex;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue, &l_sbeDownFifoRespBuf[0]);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeModifyScom (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeModifyScom "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ sbeModifyScomReqMsg_t l_modifyScomMsg;
+
+ do
+ {
+ uint16_t l_primStatus = g_sbeCmdRespHdr.prim_status;
+ uint16_t l_secStatus = g_sbeCmdRespHdr.sec_status ;
+
+ // Will attempt to dequeue the following entries:
+ // Entry 1 : Operation Mode
+ // Entry 2 : Scom Register Address (0..31)
+ // Entry 3 : Scom Register Address (32..63)
+ // Entry 4 : Modifying Data (0..31)
+ // Entry 5 : Modifying Data (32..63)
+ // Entry 6 : EOT entry at the end
+
+ uint32_t l_len2dequeue = sizeof(l_modifyScomMsg)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, (uint32_t *)&l_modifyScomMsg);
+
+ // If FIFO access failure
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ uint32_t l_sbeDownFifoRespBuf[4] = {0};
+ uint32_t l_pcbpibStatus = SBE_PCB_PIB_ERROR_NONE;
+ uint32_t l_len2enqueue = 0;
+
+ // Modifying Data
+ uint64_t l_modifyingData = l_modifyScomMsg.getModifyingData();
+
+ SBE_DEBUG(SBE_FUNC"OpMode[0x%02X], modifyingData[0x%016X]",
+ l_modifyScomMsg.opMode,
+ SBE::higher32BWord(l_modifyingData),
+ SBE::lower32BWord(l_modifyingData));
+
+ // The following steps need to be done as part of this command :
+ // 1. Read Register Data (getscom)
+ // 2. 'AND' the Mask with the data read from register
+ // 3. 'OR' the modifying data with the result of step 2
+ // 4. Write the result of step 3 into the register (putscom)
+ do
+ {
+ // Check for a valid OpMode
+ if ( (l_modifyScomMsg.opMode != SBE_MODIFY_MODE_OR) &&
+ (l_modifyScomMsg.opMode != SBE_MODIFY_MODE_AND) &&
+ (l_modifyScomMsg.opMode != SBE_MODIFY_MODE_XOR) )
+ {
+ // Invalid Data passed
+ SBE_ERROR(SBE_FUNC"Invalid OpMode");
+ l_primStatus = SBE_PRI_INVALID_DATA;
+ l_secStatus = SBE_SEC_GENERIC_FAILURE_IN_EXECUTION;
+ break;
+ }
+
+ uint64_t l_addr = ( (uint64_t) l_modifyScomMsg.hiAddr << 32) |
+ l_modifyScomMsg.lowAddr;
+ uint64_t l_scomData = 0;
+ SBE_DEBUG(SBE_FUNC"scomAddr[0x%08X%08X]",
+ l_modifyScomMsg.hiAddr, l_modifyScomMsg.lowAddr);
+ l_rc = checkIndirectAndDoScom(true, l_addr,
+ l_scomData, l_pcbpibStatus);
+
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) // scom failed
+ {
+ SBE_ERROR(SBE_FUNC"getscom failed, l_pcbpibStatus[0x%08X],"
+ " ScomAddress[0x%08X %08X]", l_pcbpibStatus,
+ l_modifyScomMsg.hiAddr, l_modifyScomMsg.lowAddr);
+ l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE;
+ l_secStatus = l_rc;
+ break;
+ }
+
+ if (l_modifyScomMsg.opMode == SBE_MODIFY_MODE_OR)
+ {
+ l_modifyingData |= l_scomData;
+ }
+ else if (l_modifyScomMsg.opMode == SBE_MODIFY_MODE_AND)
+ {
+ l_modifyingData &= l_scomData;
+ }
+ else
+ {
+ l_modifyingData ^= l_scomData;
+ }
+
+ // Write the modified data
+ l_rc = checkIndirectAndDoScom(false, l_addr,
+ l_modifyingData, l_pcbpibStatus);
+
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) // scom failed
+ {
+ SBE_ERROR(SBE_FUNC"putscom failed, l_pcbpibStatus[0x%08X],"
+ " ScomAddress[0x%08X%08X]", l_pcbpibStatus,
+ l_modifyScomMsg.hiAddr, l_modifyScomMsg.lowAddr);
+ SBE_ERROR(SBE_FUNC"modifyingData[0x%08X%08X]",
+ SBE::higher32BWord(l_modifyingData),
+ SBE::lower32BWord(l_modifyingData));
+ l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE;
+ l_secStatus = l_rc;
+ break;
+ }
+ } while (false);
+
+ // Build the response header packet
+
+ uint32_t l_curIndex = 0;
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_curIndex,
+ l_primStatus,
+ l_secStatus,
+ l_pcbpibStatus);
+
+ // Now enqueue into the downstream FIFO
+ l_len2enqueue = ++l_curIndex;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue,
+ (uint32_t *)&l_sbeDownFifoRespBuf);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbePutScomUnderMask (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbePutScomUnderMask "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbePutScomUnderMaskReqMsg_t l_putScomUmaskMsg;
+
+ do
+ {
+ uint16_t l_primStatus = g_sbeCmdRespHdr.prim_status;
+ uint16_t l_secStatus = g_sbeCmdRespHdr.sec_status ;
+
+ // Will attempt to dequeue the following entries:
+ // Entry 1 : Scom Register Address (0..31)
+ // Entry 2 : Scom Register Address (32..63)
+ // Entry 3 : Modifying Data (0..31)
+ // Entry 4 : Modifying Data (32..63)
+ // Entry 5 : Mask Data (0..31)
+ // Entry 6 : Mask Data (32..63)
+ // Entry 7 : EOT entry at the end
+
+ uint32_t l_len2dequeue = sizeof(l_putScomUmaskMsg)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue,
+ (uint32_t *)&l_putScomUmaskMsg);
+
+ // If FIFO access failure
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ uint32_t l_sbeDownFifoRespBuf[4] = {0};
+ uint32_t l_pcbpibStatus = SBE_PCB_PIB_ERROR_NONE;
+ uint32_t l_len2enqueue = 0;
+
+ SBE_DEBUG(SBE_FUNC"scomAddr[0x%08X%08X],"
+ "modifyingData[0x%08X%08X]",
+ l_putScomUmaskMsg.hiAddr,
+ l_putScomUmaskMsg.lowAddr,
+ l_putScomUmaskMsg.hiInputData,
+ l_putScomUmaskMsg.lowInputData);
+ SBE_INFO(SBE_FUNC"maskData[0x%08X%08X]",
+ l_putScomUmaskMsg.hiMaskData,
+ l_putScomUmaskMsg.lowMaskData);
+
+ // PutScomUnderMask formula:
+ // dest_reg = (dest_reg & ~input_mask) | (input_data & input_mask)
+
+ do
+ {
+ uint64_t l_scomData = 0;
+
+ uint64_t l_addr = ( (uint64_t) l_putScomUmaskMsg.hiAddr << 32) |
+ l_putScomUmaskMsg.lowAddr;
+ l_rc = checkIndirectAndDoScom(true, l_addr,
+ l_scomData, l_pcbpibStatus);
+
+ if (l_rc == SBE_SEC_OPERATION_SUCCESSFUL) // scom success
+ {
+ l_putScomUmaskMsg.getScomData(l_scomData);
+
+ // Write the modified data
+ l_rc = checkIndirectAndDoScom(false, l_addr,
+ l_scomData, l_pcbpibStatus);
+ }
+
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) // scom failed
+ {
+ SBE_ERROR(SBE_FUNC"scom failed, l_pcbpibStatus[0x%08X], "
+ "ScomAddress[0x%08X%08X]", l_pcbpibStatus,
+ l_putScomUmaskMsg.hiAddr,
+ l_putScomUmaskMsg.lowAddr);
+ SBE_ERROR(SBE_FUNC"modifyingData[0x%08X%08X]"
+ "maskData[0x%08X%08X]",
+ l_putScomUmaskMsg.hiInputData,
+ l_putScomUmaskMsg.lowInputData,
+ l_putScomUmaskMsg.hiMaskData,
+ l_putScomUmaskMsg.lowMaskData);
+
+ l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE;
+ l_secStatus = l_rc;
+ break;
+ }
+ } while (false);
+
+ // Build the response header packet
+ uint32_t l_curIndex = 0;
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_curIndex,
+ l_primStatus,
+ l_secStatus,
+ l_pcbpibStatus);
+
+ // Now enqueue into the downstream FIFO
+ l_len2enqueue = ++l_curIndex;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue, &l_sbeDownFifoRespBuf[0]);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeMultiScom (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeMultiScom "
+ return 0;
+ #undef SBE_FUNC
+}
+
diff --git a/src/sbefw/sbecmdscomaccess.H b/src/sbefw/sbecmdscomaccess.H
new file mode 100644
index 00000000..8a4a4a28
--- /dev/null
+++ b/src/sbefw/sbecmdscomaccess.H
@@ -0,0 +1,93 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdscomaccess.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdscomaccess.H
+ *
+ * @brief This file contains the Interfaces for the SCOM Access chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDSCOMACCESS_H
+#define __SBEFW_SBECMDSCOMACCESS_H
+
+#include <stdint.h>
+
+/**
+ * @brief sbeDownFifoGetStatus : Write data into Downstream FIFO
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetScom (uint8_t *i_pArg);
+
+
+/**
+ * @brief sbeDownFifoGetStatus : Write data into Downstream FIFO
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbePutScom (uint8_t *i_pArg);
+
+
+/**
+ * @brief sbeModifyScom : Modify the Scom data
+ * This chipOp needs to do the following
+ * 1. Read Register Data (getscom)
+ * 2. modify the scomData using the given op mode
+ * 3. Write the modified Data into the Register (putscom)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeModifyScom (uint8_t *i_pArg);
+
+
+/**
+ * @brief sbePutScomUnderMask : Write data into Downstream FIFO
+ * The following steps need to be done as part of this command :
+ * 1. Read Register Data (getscom)
+ * 2. 'AND' the Mask with the data read from register
+ * 3. 'OR' the modifying data with the result of step 2
+ * 4. Write the result of step 3 into the register (putscom)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbePutScomUnderMask (uint8_t *i_pArg);
+
+/**
+ * @brief sbeMultiScom:
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeMultiScom (uint8_t *i_pArg);
+
+#endif /* __SBEFW_SBECMDSCOMACCESS_H */
diff --git a/src/sbefw/sbecmdsram.C b/src/sbefw/sbecmdsram.C
new file mode 100644
index 00000000..ac11ffc6
--- /dev/null
+++ b/src/sbefw/sbecmdsram.C
@@ -0,0 +1,337 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdsram.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdsram.C
+ *
+ * @brief This file contains the SBE Sram Access chipOps
+ *
+ */
+
+#include "sbecmdsram.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbeFifoMsgUtils.H"
+#include "sberegaccess.H"
+
+#include "fapi2.H"
+#include "p9_pm_ocb_init.H"
+#include "p9_pm_ocb_indir_setup_linear.H"
+#include "p9_pm_ocb_indir_access.H"
+#include "p9_perv_scom_addresses.H"
+
+using namespace fapi2;
+
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeOccSramAccess_Wrap Occ Sran Access Wrapper function
+//
+// @param [in] i_isGetFlag Flag to indicate the sram Access Type
+// true : GetOccSram ChipOp
+// false : PutOccSram ChipOp
+//
+// @return RC from the underlying FIFO utility
+///////////////////////////////////////////////////////////////////////
+uint32_t sbeOccSramAccess_Wrap(const bool i_isGetFlag)
+{
+ #define SBE_FUNC " sbeOccSramAccess_Wrap "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ ReturnCode l_fapiRc = FAPI2_RC_SUCCESS;
+
+ sbeRespGenHdrWithLen_t l_respHdr;
+ l_respHdr.init();
+ sbeResponseFfdc_t l_ffdc;
+
+ // Total Returned length from the procedure
+ uint32_t l_totalReturnLen = 0;
+
+ // Create the req struct for the OCC Sram Chip-op
+ sbeOccSramAccessReqMsgHdr_t l_req = {0};
+
+ // Check if True - Get / False - Put
+ p9ocb::PM_OCB_ACCESS_OP l_ocb_access =
+ (i_isGetFlag)? p9ocb::OCB_GET : p9ocb::OCB_PUT;
+
+ do
+ {
+ // Get the Req Struct Size Data from upstream Fifo
+ uint32_t l_len2dequeue = sizeof(l_req) / sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue,
+ (uint32_t *)&l_req,
+ i_isGetFlag);
+
+ // If FIFO failure
+ if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ SBE_INFO("mode [0x%08X] addr[0x%08X] len[0x%08X]",
+ l_req.mode, l_req.addr, l_req.len);
+
+ // Get the Proc Chip Target to be passed in to the procedure call
+ Target<fapi2::TARGET_TYPE_PROC_CHIP> l_proc = plat_getChipTarget();
+
+ // Do linear setup for indirect access HWP for Chan0, Chan2 and Chan3
+ // For Circular Mode, Chan1 is assumed to be setup by default
+ // Linear mode is setup with Linear streaming mode only
+
+ // Sram Access condition to pass valid address during the first access
+ bool l_validAddrForFirstAccess = true;
+
+ // Channel Selection based on Mode as well as Fsp attchament
+ p9ocb::PM_OCB_CHAN_NUM l_chan = p9ocb::OCB_CHAN0;
+ switch(l_req.mode)
+ {
+ case NORMAL_MODE:
+ if(false == SbeRegAccess::theSbeRegAccess().isFspSystem())
+ {
+ l_chan = p9ocb::OCB_CHAN2;
+ }
+ break;
+
+ case DEBUG_MODE:
+ l_chan = p9ocb::OCB_CHAN3;
+ break;
+
+ case CIRCULAR_MODE:
+ l_chan = p9ocb::OCB_CHAN1;
+ l_validAddrForFirstAccess = false;
+ break;
+
+ default:
+ SBE_ERROR(SBE_FUNC "Invalid Mode Passed by User");
+ l_rc = SBE_SEC_GENERIC_FAILURE_IN_EXECUTION;
+ l_respHdr.respHdr.setStatus( SBE_PRI_INVALID_DATA, l_rc);
+ break;
+ }
+ if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ break;
+ }
+
+ // Setup Needs to be called in Normal and Debug Mode only
+ if( (l_req.mode == NORMAL_MODE) || (l_req.mode == DEBUG_MODE) )
+ {
+ l_fapiRc = p9_pm_ocb_indir_setup_linear(l_proc, l_chan,
+ p9ocb::OCB_TYPE_LINSTR,
+ l_req.addr);
+ if(l_fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "p9_pm_ocb_indir_setup_linear failed, "
+ "Channel[0x%02X] Addr[0x%08X]",
+ l_chan, l_req.addr);
+
+ // Respond with HWP FFDC
+ l_respHdr.respHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+ }
+
+ //Create a 128 Byte Buffer - 16 64-Bit buffer
+ // This is our Granule size as well for this HWP
+ uint32_t l_getBuf[SBE_OCC_SRAM_GRANULE/SBE_32BIT_ALIGN_FACTOR] = {};
+ uint32_t l_remainingLen = l_req.len; // Initialize with Total Len
+ uint32_t l_lenPassedToHwp = 0;
+ uint32_t l_actLen = 0; // Return Len from Hwp not used
+
+ while(l_remainingLen)
+ {
+ if(l_remainingLen <= SBE_OCC_SRAM_GRANULE)
+ {
+ l_lenPassedToHwp = l_remainingLen;
+ }
+ else
+ {
+ l_lenPassedToHwp = SBE_OCC_SRAM_GRANULE;
+ }
+ l_remainingLen = l_remainingLen - l_lenPassedToHwp;
+
+ // Fetch buffer from Upstream Fifo for the HWP if it is PutOCC Sram
+ if(!i_isGetFlag)
+ {
+ l_len2dequeue = (l_lenPassedToHwp/SBE_32BIT_ALIGN_FACTOR);
+ l_rc = sbeUpFifoDeq_mult ( l_len2dequeue,
+ l_getBuf,
+ false);
+ // If there was an underlying FIFO operation failure
+ if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+ }
+
+ // Don't need to put any check for Linear/Circular - It's the same
+ // API for access, For circular valid address flag is false, Hwp
+ // doesn't need the address field from us.
+ l_fapiRc = p9_pm_ocb_indir_access(
+ l_proc,
+ l_chan,
+ l_ocb_access, // Get/Put
+ (l_lenPassedToHwp/SBE_64BIT_ALIGN_FACTOR), // 64-bit aligned
+ l_validAddrForFirstAccess, // If requested addr is valid
+ l_req.addr, // Requested Addr being passed
+ l_actLen, // O/p from hwp not used
+ (uint64_t *)l_getBuf); // O/p buffer
+ if(l_fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "p9_pm_ocb_indir_access failed, "
+ "Channel[0x%02X] Addr[0x%08X] 64Bit Aligned Len[0x%08X]",
+ l_chan, l_req.addr, (l_lenPassedToHwp/SBE_64BIT_ALIGN_FACTOR));
+
+ // Respond with HWP FFDC
+ l_respHdr.respHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+
+ l_totalReturnLen = l_totalReturnLen + l_lenPassedToHwp;
+ // Change this to false, so that Indirect Access Hwp doesn't
+ // reset the Address to starting point.
+ l_validAddrForFirstAccess = false;
+
+ if(i_isGetFlag) // Get Occ Sram
+ {
+ l_len2dequeue = (l_lenPassedToHwp/SBE_32BIT_ALIGN_FACTOR);
+ // Push this into the downstream FIFO
+ l_rc = sbeDownFifoEnq_mult (l_len2dequeue, l_getBuf);
+
+ // If FIFO failure
+ if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+ }
+ } // End of while Put/Get from Hwp
+
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ break;
+ }
+
+ do
+ {
+ l_len2dequeue = 0;
+ if (!i_isGetFlag)
+ {
+ // If there was a HWP failure for put sram occ request,
+ // need to Flush out upstream FIFO, until EOT arrives
+ if ( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL,
+ true, true);
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ break;
+ }
+ }
+ // For other success paths, just attempt to offload
+ // the next entry, which is supposed to be the EOT entry
+ else
+ {
+ l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL, true);
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ break;
+ }
+ }
+ }
+
+ // Distance to Header is minus the length field in the response
+ // buffer. So when we do sizeof(l_respHdr) It will add an extra byte
+ // for the length. So it compensates for the length, if we start the
+ // distance from hdr as zero.
+ uint32_t l_dist2Hdr = 0;
+
+ // Now enqueue the minimum response header
+ // first enqueue the length of data actually written
+ l_respHdr.setLength(l_totalReturnLen);
+ uint32_t l_len = sizeof(l_respHdr) / sizeof(uint32_t);
+ l_rc = sbeDownFifoEnq_mult(l_len, (uint32_t *)(&l_respHdr));
+
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ break;
+ }
+
+ l_dist2Hdr += l_len;
+
+ // Enqueue FFDC data if there is one
+ if( l_ffdc.getRc() )
+ {
+ l_len = sizeof(l_ffdc) / sizeof(uint32_t);
+ l_rc = sbeDownFifoEnq_mult (l_len, (uint32_t *)(&l_ffdc));
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ break;
+ }
+
+ l_dist2Hdr += l_len;
+ }
+
+ l_len = sizeof(l_dist2Hdr) / sizeof(uint32_t);
+ l_rc = sbeDownFifoEnq_mult ( l_len, &l_dist2Hdr);
+
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ break;
+ }
+ }while(0);
+ }while(0);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbePutOccSram (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbePutOccSram "
+ return sbeOccSramAccess_Wrap (false);
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeGetOccSram (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeGetOccSram "
+ return sbeOccSramAccess_Wrap (true);
+ #undef SBE_FUNC
+}
+
diff --git a/src/sbefw/sbecmdsram.H b/src/sbefw/sbecmdsram.H
new file mode 100644
index 00000000..1c86aa2b
--- /dev/null
+++ b/src/sbefw/sbecmdsram.H
@@ -0,0 +1,64 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdsram.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbecmdsram.H
+ *
+ * @brief This file contains the Interfaces for the Sram Access chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDSRAM_H
+#define __SBEFW_SBECMDSRAM_H
+
+#include <stdint.h>
+
+static const uint8_t SBE_32BIT_ALIGN_FACTOR = 4;
+static const uint8_t SBE_64BIT_ALIGN_FACTOR = 8;
+
+static const uint64_t SBE_FWCTRLFLG3_FSP_ATTACHED = 0X1000000000000000;
+
+/*
+ * @brief Granule size in Bytes for 'Get from Hwp'/'Put to Hwp'
+ */
+static const uint32_t SBE_OCC_SRAM_GRANULE = 128;
+
+/**
+ * @brief sbeGetOccSram : Implements SBE Get Occ Sram ChipOp
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetOccSram (uint8_t *i_pArg);
+
+/**
+ * @brief sbePutOccSram : Implements SBE Put Occ Sram ChipOp
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbePutOccSram (uint8_t *i_pArg);
+
+#endif /* __SBEFW_SBECMDSRAM_H */
diff --git a/src/sbefw/sbeerrorcodes.H b/src/sbefw/sbeerrorcodes.H
new file mode 100644
index 00000000..2e37bb2b
--- /dev/null
+++ b/src/sbefw/sbeerrorcodes.H
@@ -0,0 +1,49 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeerrorcodes.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbeerrorcodes.H
+ *
+ * @brief This file contains the SBE internal error status codes
+ *
+ */
+
+#ifndef __SBEFW_SBEERRORCODES_H
+#define __SBEFW_SBEERRORCODES_H
+
+#include <stdint.h>
+
+
+/**
+ * @brief enums SBE internal error codes
+ *
+*/
+enum sbeInternalResponseCodes
+{
+ SBE_FIFO_RESET_RECEIVED = 0xFA00,
+ SBE_FIFO_RESET_HANDLING_FAILED = 0xFB00,
+ SBE_FUNC_NOT_SUPPORTED = 0xFC00,
+};
+
+
+#endif // __SBEFW_SBEERRORCODES_H \ No newline at end of file
diff --git a/src/sbefw/sbeevents.H b/src/sbefw/sbeevents.H
new file mode 100644
index 00000000..6506a050
--- /dev/null
+++ b/src/sbefw/sbeevents.H
@@ -0,0 +1,96 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeevents.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbeevents.H
+ *
+ * @brief This file contains interfaces pertaining to the events for state
+ * transition trigger.
+ *
+ */
+
+#ifndef __SBEFW_SBEEVENTS_H
+#define __SBEFW_SBEEVENTS_H
+
+/**
+ * @brief An enumeration of all SBE state transition events
+ *
+ */
+enum sbeEvent
+{
+ SBE_CONTINUE_BOOT_PLCK_EVENT = 0x0, // From FFDC State
+ SBE_CONTINUE_BOOT_RUNTIME_EVENT = 0x1, // From FFDC State
+ SBE_RUNTIME_EVENT = 0x2, // From FFDC/Unknown/ISTEP/IPLING State
+ SBE_ISTEP_EVENT = 0x3, // From FFDC/Unknown State
+ SBE_PLCK_EVENT = 0x4, // From FFDC/Unknown state
+ SBE_DUMP_FAILURE_EVENT = 0x5, // From IPLING/RUNTIME/MPIPL/DMT/Unknown State
+ SBE_ENTER_MPIPL_EVENT = 0x6, // From Runtime State
+ SBE_CONTINUE_MPIPL_EVENT = 0x7, // From MPIPL Wait State
+ SBE_ABORT_EVENT = 0x8, // From Any state
+ SBE_DMT_ENTER_EVENT = 0x9, // From Runtime State
+ SBE_DMT_COMP_EVENT = 0xA, // From DMT State
+ SBE_FAILURE_EVENT = 0xB, // From Any State
+ SBE_FFDC_COLLECT_EVENT = 0xC, // From Unknown State
+};
+
+// Maximum number of Events per State
+enum maxEventPerState
+{
+ SBE_STATE_UNKNOWN_MAX_EVENT = 5,
+ SBE_STATE_FFDC_COLLECT_MAX_EVENT = 4,
+ SBE_STATE_IPLING_MAX_EVENT = 4,
+ SBE_STATE_ISTEP_MAX_EVENT = 3,
+ SBE_STATE_RUNTIME_MAX_EVENT = 4,
+ SBE_STATE_MPIPL_MAX_EVENT = 2,
+ SBE_STATE_DMT_MAX_EVENT = 1,
+ SBE_STATE_DUMP_MAX_EVENT = 0,
+ SBE_STATE_FAILURE_MAX_EVENT = 0,
+ SBE_STATE_QUIESCE_MAX_EVENT = 0,
+ SBE_STATE_ABORT_MAX_EVENT = 0,
+
+ // Total number of State Transition Events, Addition of all the above
+ SBE_MAX_TRANSITIONS = 23,
+};
+
+
+// Entry Point to stateTransitionStr_t Map Structure, This adds up all the state
+// transition of the previous state, If any more transition is added, this will
+// add up to all subsequent entries. This is closely mapped with the sbestates.H
+// as well.
+enum entryToStateMap
+{
+ SBE_STATE_UNKNOWN_ENTRY_TO_MAP = 0,
+ SBE_STATE_FFDC_COLLECT_ENTRY_TO_MAP = SBE_STATE_UNKNOWN_ENTRY_TO_MAP + SBE_STATE_UNKNOWN_MAX_EVENT, // 5
+ SBE_STATE_IPLING_ENTRY_TO_MAP = SBE_STATE_FFDC_COLLECT_ENTRY_TO_MAP + SBE_STATE_FFDC_COLLECT_MAX_EVENT, //9
+ SBE_STATE_ISTEP_ENTRY_TO_MAP = SBE_STATE_IPLING_ENTRY_TO_MAP + SBE_STATE_IPLING_MAX_EVENT, //13
+ SBE_STATE_RUNTIME_ENTRY_TO_MAP = SBE_STATE_ISTEP_ENTRY_TO_MAP + SBE_STATE_ISTEP_MAX_EVENT, //16
+ SBE_STATE_MPIPL_ENTRY_TO_MAP = SBE_STATE_RUNTIME_ENTRY_TO_MAP + SBE_STATE_RUNTIME_MAX_EVENT, //20
+ SBE_STATE_DMT_ENTRY_TO_MAP = SBE_STATE_MPIPL_ENTRY_TO_MAP + SBE_STATE_MPIPL_MAX_EVENT, //22
+ SBE_STATE_DUMP_ENTRY_TO_MAP = SBE_STATE_DMT_ENTRY_TO_MAP + SBE_STATE_DMT_MAX_EVENT, //23
+ SBE_STATE_FAILURE_ENTRY_TO_MAP = SBE_STATE_DUMP_ENTRY_TO_MAP + SBE_STATE_DUMP_MAX_EVENT, //23
+ SBE_STATE_QUIESCE_ENTRY_TO_MAP = SBE_STATE_FAILURE_ENTRY_TO_MAP + SBE_STATE_FAILURE_MAX_EVENT, //23
+ SBE_STATE_ABORT_ENTRY_TO_MAP = SBE_STATE_QUIESCE_ENTRY_TO_MAP + SBE_STATE_QUIESCE_MAX_EVENT, //23
+};
+
+#endif //__SBEFW_SBEEVENTS_H
+
diff --git a/src/sbefw/sbeexeintf.H b/src/sbefw/sbeexeintf.H
new file mode 100644
index 00000000..8a8aff66
--- /dev/null
+++ b/src/sbefw/sbeexeintf.H
@@ -0,0 +1,256 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeexeintf.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbeexeintf.H
+ *
+ * @brief This file contains the SBE control loop firmware details like
+ * - Thread priority enums
+ * - Thread stack size and space enums
+ * - Thread sub-rountine declarations
+ * - IRQ setup and ISR declarations
+ * - Other Common declaration among all the threads
+ */
+
+#ifndef __SBEFW_SBE_H
+#define __SBEFW_SBE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "pk.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @brief enums for priorities for thread creation
+ *
+ */
+typedef enum
+{
+ THREAD_PRIORITY_MAX_0,
+ THREAD_PRIORITY_1,
+ THREAD_PRIORITY_2,
+ THREAD_PRIORITY_3,
+ THREAD_PRIORITY_4,
+ THREAD_PRIORITY_5,
+ THREAD_PRIORITY_6,
+ THREAD_PRIORITY_7,
+ THREAD_PRIORITY_8,
+ THREAD_PRIORITY_MIN_30 = 30,
+} sbeThreadPriorities ;
+
+/**
+ * @brief enums for thread stack sizes
+ * - Non-Critical Stack used by non-critical interrupt handlers
+ * - Critical Stack used for critical interrupts
+ * - Stacks for each thread
+ *
+ * @TODO via RTC : 128657
+ * - Measure the actual thread stack utilization
+ * - This will be a continuous activity
+ */
+enum sbeThreadStackSize
+{
+ SBE_NONCRITICAL_STACK_SIZE = 256,
+ SBE_THREAD_ASYNC_CMD_PROC_STACK_SIZE = 256,
+ SBE_THREAD_CMD_RECV_STACK_SIZE = 512,
+ SBE_THREAD_SYNC_CMD_PROC_STACK_SIZE = 2048,
+};
+
+/**
+ * @brief Global semaphore : g_sbeSemCmdRecv
+ *
+ * This is used to synchronize between the ISR and
+ * the command receiver thread.
+ *
+ */
+extern PkSemaphore g_sbeSemCmdRecv;
+
+/**
+ * @brief Global semaphore : g_sbeSemCmdProcess
+ *
+ * This is used to synchronize between command receiver thread
+ * and synchronous command processor thread.
+ *
+ */
+extern PkSemaphore g_sbeSemCmdProcess;
+
+
+/**
+ * @brief SBE Interface source
+ *
+ */
+typedef enum
+{
+ SBE_INTERFACE_UNKNOWN = 0x00,
+ SBE_INTERFACE_FIFO = 0x01,
+ SBE_INTERFACE_PSU = 0x02,
+ SBE_INTERFACE_FIFO_RESET = 0x04,
+} sbeInterfaceSrc_t;
+
+/*
+ * @brief Enum for Handler, handling the interrupt and setting/clearing the
+ * interrupt variable
+ */
+typedef enum
+{
+ SBE_ALL_HANDLER = 0x0,
+ SBE_INTERRUPT_ROUTINE = 0x1,
+ SBE_RX_ROUTINE = 0x2,
+ SBE_PROC_ROUTINE = 0x3,
+} sbeHandler_t;
+
+/**
+ * @brief structure for SBE external Interrupt handling
+ *
+ */
+typedef struct
+{
+ uint8_t intrSource;
+ uint8_t rxThrIntrSource;
+ uint8_t procThrIntrSource;
+
+ void setIntrSource(const sbeHandler_t i_handler,
+ const sbeInterfaceSrc_t i_val)
+ {
+ switch(i_handler)
+ {
+ case SBE_INTERRUPT_ROUTINE: intrSource |= i_val; break;
+ case SBE_RX_ROUTINE: rxThrIntrSource |= i_val; break;
+ case SBE_PROC_ROUTINE: procThrIntrSource |= i_val; break;
+ case SBE_ALL_HANDLER: break;
+ }
+ }
+
+ void clearIntrSource(const sbeHandler_t i_handler,
+ const sbeInterfaceSrc_t i_val)
+ {
+ switch(i_handler)
+ {
+ case SBE_INTERRUPT_ROUTINE: intrSource &= ~i_val; break;
+ case SBE_RX_ROUTINE: rxThrIntrSource &= ~i_val; break;
+ case SBE_PROC_ROUTINE: procThrIntrSource &= ~i_val; break;
+ case SBE_ALL_HANDLER:
+ {
+ intrSource &= ~i_val;
+ rxThrIntrSource &= ~i_val;
+ procThrIntrSource &= ~i_val;
+ break;
+ }
+ }
+ }
+
+ bool isSet (const sbeHandler_t i_handler, const sbeInterfaceSrc_t i_val)
+ {
+ bool l_ret = false;
+ switch(i_handler)
+ {
+ case SBE_INTERRUPT_ROUTINE: l_ret = (intrSource & i_val); break;
+ case SBE_RX_ROUTINE: l_ret = (rxThrIntrSource & i_val); break;
+ case SBE_PROC_ROUTINE: l_ret = (procThrIntrSource & i_val); break;
+ case SBE_ALL_HANDLER: break;
+ }
+ return l_ret;
+ }
+} sbeIntrHandle_t;
+extern sbeIntrHandle_t g_sbeIntrSource ;
+
+
+/**
+ * @TODO via RTC : 128658
+ * Mutex protect the critical data
+ * e.g., add Mutex g_sbeMutCmdReqBuf etc.
+ */
+
+/**
+ * @brief sbeCommandReceiver_routine
+ * The major responsibilities of this thread are :
+ * - Determine the reason for the interrupt
+ * - FIFO New data
+ * - FIFO reset
+ * - Host services
+ * - Dequeue the mandatory 2 entry header from upstream FIFO
+ * - Command input data validation
+ * - SBE State and pre-requirements validation
+ * - FFDC collection and FIFO flush upon validation failure
+ * - Unblock SBE command processor thread
+ * - Perform FIFO reset upon request from SP
+ *
+ * @param[in] i_pArg - Any buffer needed to be passed to the thread routine
+ */
+void sbeCommandReceiver_routine(void *i_pArg);
+
+/**
+ * @brief sbeSyncCommandProcessor_routine
+ * The major responsibilities of this thread are :
+ * - Dequeue data payload from upstream FIFO
+ * - Un-marshalling of the command request data
+ * - Blacklist validation
+ * - FFDC collection upon validation failure
+ * - Invoke the corresponding Hardware access utility
+ * or the HWP corresponding to the chipOp request
+ * - FFDC collection and FIFO flush upon hardware access / HWP failure
+ * - Build the response buffer with the data and the header
+ * - Enqueue the response into the Downstream FIFO
+ * - Un-mask the new data available interrupt
+ *
+ * @param[in] i_pArg - Any buffer needed to be passed to the thread routine
+ */
+void sbeSyncCommandProcessor_routine(void *i_pArg);
+
+/**
+ * @brief sbeAsyncCommandProcessor_routine
+ * @TODO RTC via : 130392
+ * Add infrastructure for host interface
+ *
+ * @param[in] i_pArg - Any buffer needed to be passed to the thread routine
+ */
+void sbeAsyncCommandProcessor_routine(void *i_pArg);
+
+
+/* @brief ISR for all SBE External Interrupts
+ * - FIFO : New data available
+ * - FIFO : Reset Request
+ * - PSU : New data available
+ *
+ * @param[in/out] i_pArg - Any buffer needed to be passed to the handler
+ * @param[in] i_irq - IRQ number as defined in the SBE PPE spec
+ */
+void sbe_interrupt_handler(void* i_pArg, PkIrqId i_irq);
+
+
+/* brief : Register SBE interrupt handlers and enable the IRQs
+ *
+ * @return int PK_OK - Success (IRQ Setup was successful)
+ * PK_INVALID_ARGUMENT_IRQ_HANDLER - Invalid argument passed
+ * (Code bug)
+ *
+ */
+int sbeIRQSetup (void);
+
+
+#endif /* __SBEFW_SBE_H */
diff --git a/src/sbefw/sbefifo.H b/src/sbefw/sbefifo.H
new file mode 100644
index 00000000..47ce5beb
--- /dev/null
+++ b/src/sbefw/sbefifo.H
@@ -0,0 +1,227 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbefifo.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbefifo.H
+ *
+ * @brief This file contains basic SBE FIFO hardware specific
+ * definitions and operations.
+ *
+ */
+
+#ifndef __SBEFW_SBEFIFO_H
+#define __SBEFW_SBEFIFO_H
+
+#include "sbeexeintf.H"
+#include "sbetrace.H"
+#include "ppe42_scom.h"
+#include "sbe_sp_intf.H"
+#include "sbeSpMsg.H"
+
+/**
+ * @brief SBE FIFO Access addresses
+ *
+ */
+const uint32_t SBE_FIFO_BASE = 0x000B0000;
+
+const uint32_t SBE_UPSTREAM_FIFO_DEQ_ADD = SBE_FIFO_BASE + 0x0000;
+const uint32_t SBE_UPSTREAM_FIFO_STATUS = SBE_FIFO_BASE + 0x0001;
+const uint32_t SBE_UPSTREAM_FIFO_SIGNAL_EOT = SBE_FIFO_BASE + 0x0002;
+const uint32_t SBE_UPSTREAM_FIFO_REQ_RESET = SBE_FIFO_BASE + 0x0003;
+const uint32_t SBE_UPSTREAM_FIFO_PERFORM_RESET = SBE_FIFO_BASE + 0x0004;
+const uint32_t SBE_UPSTREAM_FIFO_ACK_EOT = SBE_FIFO_BASE + 0x0005;
+
+const uint32_t SBE_DOWNSTREAM_FIFO_ENQ_ADD = SBE_FIFO_BASE + 0x0010;
+const uint32_t SBE_DOWNSTREAM_FIFO_STATUS = SBE_FIFO_BASE + 0x0011;
+const uint32_t SBE_DOWNSTREAM_FIFO_SIGNAL_EOT = SBE_FIFO_BASE + 0x0012;
+const uint32_t SBE_DOWNSTREAM_FIFO_REQ_RESET = SBE_FIFO_BASE + 0x0013;
+const uint32_t SBE_DOWNSTREAM_FIFO_PERFORM_RESET = SBE_FIFO_BASE + 0x0014;
+const uint32_t SBE_DOWNSTREAM_FIFO_ACK_EOT = SBE_FIFO_BASE + 0x0015;
+
+/**
+ * @brief SBE Upstream FIFO Status bits
+ *
+ */
+
+typedef struct
+{
+ uint32_t valid_flag:1; // Bit 0
+ uint32_t eot_flag:1; // Bit 1
+ uint32_t parity_err:1; // Bit 2
+ uint32_t reserved3_5:3; // Bit 3:5
+ uint32_t req_upfifo_reset:1; // Bit 6
+ uint32_t req_downfifo_reset:1; // Bit 7
+ uint32_t signaling_eot:1; // Bit 8
+ uint32_t reserved9:1; // Bit 9
+ uint32_t fifo_full:1; // Bit 10
+ uint32_t fifo_empty:1; // Bit 11
+ uint32_t fifo_entry_count:4; // Bit 12:15
+ uint32_t fifo_valid_flags:8; // Bit 16:23
+ uint32_t fifo_eot_flags:8; // Bit 24:31
+
+} sbe_upfifo_status_t ;
+
+/**
+ * @brief 64-bit DW structure for Upstream FIFO Dequeue
+ * or Downstream FIFO Enqueue
+ * For Upstream FIFO,
+ * Bit 0 - 31 : Data, Bit 32 - 63 : Status
+ * For Downstream FIFO,
+ * Bit 0 - 31 : Data, Bit 32 - 63 : Unused
+ *
+ */
+typedef struct
+{
+ uint32_t fifo_data;
+
+ // The following status field is applicable only for
+ // upstream FIFO access and will remain reserved for
+ // downstream FIFO access
+ sbe_upfifo_status_t statusOrReserved;
+} sbeFifoEntry_t ;
+
+
+/**
+ * @brief 64-bit DW structure for Upstream FIFO Status Reg Read
+ * Bit 0 - 31 : Status Data, Bit 32 - 63 : Unused
+ *
+ */
+typedef struct
+{
+ sbe_upfifo_status_t upfifo_status;
+ uint32_t reserved;
+} sbeUpFifoStatusReg_t ;
+
+
+/**
+ * @brief SBE Downstream FIFO Status bits
+ *
+ */
+typedef struct
+{
+ uint32_t reserved0_1:2; // Bit 0:1
+ uint32_t parity_err:1; // Bit 2
+ uint32_t reserved3_5:3; // Bit 3:5
+ uint32_t req_downfifo_reset:1; // Bit 6
+ uint32_t req_upfifo_reset:1; // Bit 7
+ uint32_t signaling_eot:1; // Bit 8
+ uint32_t reserved9:1; // Bit 9
+ uint32_t fifo_full:1; // Bit 10
+ uint32_t fifo_empty:1; // Bit 11
+ uint32_t fifo_entry_count:4; // Bit 12:15
+ uint32_t fifo_valid_flags:8; // Bit 16:23
+ uint32_t fifo_eot_flags:8; // Bit 24:31
+
+} sbe_downfifo_status_t ;
+
+/**
+ * @brief 64-bit DW structure for Downstream FIFO Status Reg Read
+ * Bit 0 - 31 : Status Data, Bit 32 - 63 : Unused
+ *
+ */
+typedef struct
+{
+ sbe_downfifo_status_t downfifo_status;
+ uint32_t reserved;
+} sbeDownFifoStatusReg_t;
+
+/*****************************************************************/
+/** Upstream FIFO access utilities **/
+/*****************************************************************/
+
+/**
+ * @brief sbeUpFifoDeq : Read entry and status from Upstream FIFO
+ *
+ * @param[out] 64-Bit Data read from Upstream FIFO
+ *
+ * @return Rc from the underlying scom utility
+ *
+ */
+extern inline uint32_t sbeUpFifoDeq (uint64_t *o_data)
+{
+ /* For SBE FIFO (PIB) access, chiplet ID should be passed as 0 */
+ return getscom_abs(SBE_UPSTREAM_FIFO_DEQ_ADD, o_data);
+}
+
+
+/**
+ * @brief sbeUpFifoPerformReset : Perform Upstream FIFO reset request
+ *
+ * @return Rc from the underlying scom utility
+ *
+ */
+extern inline uint32_t sbeUpFifoPerformReset (void)
+{
+ SBE_INFO("sbeUpFifoPerformReset");
+ return putscom_abs(SBE_UPSTREAM_FIFO_PERFORM_RESET, ((uint64_t)0x1)<<32);
+}
+
+
+/**
+ * @brief sbeUpFifoAckEot : Acknowledge EOT in Upstream FIFO
+ *
+ * @return Rc from the underlying scom utility
+ *
+ */
+extern inline uint32_t sbeUpFifoAckEot (void)
+{
+ SBE_INFO("sbeUpFifoAckEot");
+ return putscom_abs(SBE_UPSTREAM_FIFO_ACK_EOT, ((uint64_t)0x1)<<32);
+}
+
+
+/*****************************************************************/
+/** Downstream FIFO access utilities **/
+/*****************************************************************/
+
+/**
+ * @brief sbeDownFifoEnq : Write data into Downstream FIFO
+ *
+ * @param[in] 64-Bit Data write into Downstream FIFO
+ * Bit 0-31 : Data
+ * Bit 32-63 : Unused
+ *
+ * @return Rc from the underlying scom utility
+ */
+extern inline uint32_t sbeDownFifoEnq (const uint64_t i_data)
+{
+ SBE_DEBUG(">sbeDownFifoEnq");
+ return putscom_abs(SBE_DOWNSTREAM_FIFO_ENQ_ADD, i_data);
+}
+
+
+/**
+ * @brief sbeDownFifoGetStatus : Read status from downstream FIFO
+ *
+ * @param[out] 64-Bit Read status from downstream FIFO
+ * Bit 0-31 : Data
+ * Bit 32-63 : Unused
+ *
+ * @return Rc from the underlying scom utility
+ */
+extern inline uint32_t sbeDownFifoGetStatus (uint64_t *o_data)
+{
+ return getscom_abs(SBE_DOWNSTREAM_FIFO_STATUS, o_data);
+}
+
+#endif // __SBEFW_SBEFIFO_H
diff --git a/src/sbefw/sbefwfiles.mk b/src/sbefw/sbefwfiles.mk
new file mode 100644
index 00000000..24f9318e
--- /dev/null
+++ b/src/sbefw/sbefwfiles.mk
@@ -0,0 +1,48 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/sbefw/sbefwfiles.mk $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+SBEFW-CPP-SOURCES = sbemain.C
+SBEFW-CPP-SOURCES += sbeirq.C
+SBEFW-CPP-SOURCES += sbecmdreceiver.C
+SBEFW-CPP-SOURCES += sbecmdprocessor.C
+SBEFW-CPP-SOURCES += sbecmdparser.C
+SBEFW-CPP-SOURCES += sbecmdscomaccess.C
+SBEFW-CPP-SOURCES += sbecmdiplcontrol.C
+SBEFW-CPP-SOURCES += pool.C
+SBEFW-CPP-SOURCES += sbecmdgeneric.C
+SBEFW-CPP-SOURCES += sbeFifoMsgUtils.C
+SBEFW-CPP-SOURCES += sbecmdmemaccess.C
+SBEFW-CPP-SOURCES += sbeHostUtils.C
+SBEFW-CPP-SOURCES += sbecmdcntrldmt.C
+SBEFW-CPP-SOURCES += sbecmdsram.C
+SBEFW-CPP-SOURCES += sberegaccess.C
+SBEFW-CPP-SOURCES += sbecmdcntlinst.C
+SBEFW-CPP-SOURCES += sbecmdregaccess.C
+SBEFW-CPP-SOURCES += sbeFFDC.C
+SBEFW-CPP-SOURCES += sbecmdringaccess.C
+SBEFW-CPP-SOURCES += sbescom.C
+
+SBEFW-C-SOURCES =
+SBEFW-S-SOURCES =
+
+SBEFW_OBJECTS = $(SBEFW-C-SOURCES:.c=.o) $(SBEFW-CPP-SOURCES:.C=.o) $(SBEFW-S-SOURCES:.S=.o)
diff --git a/src/sbefw/sbeirq.C b/src/sbefw/sbeirq.C
new file mode 100644
index 00000000..bf445245
--- /dev/null
+++ b/src/sbefw/sbeirq.C
@@ -0,0 +1,195 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeirq.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbeirq.C
+ *
+ * @brief This sets up and registers SBE ISRs
+ *
+ */
+
+#include "sbeexeintf.H"
+#include "sbeirq.H"
+#include "sbetrace.H"
+#include "assert.h"
+
+extern sbeIntrHandle_t g_sbeIntrSource ;
+
+////////////////////////////////////////////////////////////////
+// @brief: SBE control loop ISR:
+// - FIFO new data available
+// - FIFO reset request
+// - PSU new data available
+//
+// @param[in] i_pArg - Unused
+// @param[in] i_irq - IRQ number as defined in sbeirq.h
+//
+////////////////////////////////////////////////////////////////
+void sbe_interrupt_handler (void *i_pArg, PkIrqId i_irq)
+{
+ #define SBE_FUNC " sbe_interrupt_handler "
+ SBE_ENTER(SBE_FUNC"i_irq=[0x%02X]",i_irq);
+
+ int l_rc = 0;
+
+ switch (i_irq)
+ {
+ case SBE_IRQ_HOST_PSU_INTR:
+ g_sbeIntrSource.setIntrSource(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_PSU);
+ break;
+
+ case SBE_IRQ_SBEFIFO_DATA:
+ g_sbeIntrSource.setIntrSource(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_FIFO);
+ pk_irq_disable(SBE_IRQ_SBEFIFO_RESET);
+ break;
+
+ case SBE_IRQ_SBEFIFO_RESET:
+ g_sbeIntrSource.setIntrSource(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_FIFO_RESET);
+ pk_irq_disable(SBE_IRQ_SBEFIFO_DATA);
+ break;
+
+ default:
+ SBE_ERROR(SBE_FUNC"Unknown IRQ, assert");
+ assert(0);
+ break;
+ }
+ // Mask the interrupt
+ pk_irq_disable(i_irq);
+
+ // Unblock the command receiver thread
+ l_rc = pk_semaphore_post(&g_sbeSemCmdRecv);
+ if (l_rc)
+ {
+ // If we received an error while posting the semaphore,
+ // unmask the interrupt back and assert
+ SBE_ERROR(SBE_FUNC"pk_semaphore_post failed, rc=[%d]", l_rc);
+ pk_irq_enable(i_irq);
+ assert(!l_rc);
+ }
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////////////
+// See sbeexeintf.h for more details
+////////////////////////////////////////////////////////////////
+int sbeIRQSetup (void)
+{
+ #define SBE_FUNC " sbeIRQSetup "
+ int l_rc = 0;
+ PkIrqId l_irq;
+
+ // Disable the relevant IRQs while we set them up
+ pk_irq_disable(SBE_IRQ_HOST_PSU_INTR);
+ pk_irq_disable(SBE_IRQ_SBEFIFO_DATA);
+ pk_irq_disable(SBE_IRQ_SBEFIFO_RESET);
+
+ do
+ {
+ // Register the IRQ handler with PK
+
+ // PSU New data available interrupt
+ l_irq = SBE_IRQ_HOST_PSU_INTR;
+ l_rc = pk_irq_handler_set(l_irq, sbe_interrupt_handler, NULL);
+ if(l_rc)
+ {
+ break;
+ }
+
+ // FIFO New data available interrupt
+ l_irq = SBE_IRQ_SBEFIFO_DATA;
+ l_rc = pk_irq_handler_set(l_irq, sbe_interrupt_handler, NULL);
+ if(l_rc)
+ {
+ break;
+ }
+
+ // FIFO Reset request
+ l_irq = SBE_IRQ_SBEFIFO_RESET;
+ l_rc = pk_irq_handler_set(l_irq, sbe_interrupt_handler, NULL);
+ if(l_rc)
+ {
+ break;
+ }
+
+ // Enable the IRQ
+ pk_irq_enable(SBE_IRQ_SBEFIFO_RESET);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+ pk_irq_enable(SBE_IRQ_HOST_PSU_INTR);
+ } while(false);
+
+ if (l_rc)
+ {
+ SBE_ERROR (SBE_FUNC"pk_irq_handler_set failed, IRQ=[0x%02X], "
+ "rc=[%d]", l_irq, l_rc);
+ }
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////////////
+// SBE handler for the PPE machine check interrupt
+////////////////////////////////////////////////////////////////
+// TODO: via RTC 155896 - Change the way bad scoms are handled.
+// Once HW375602 is fixed, there will be no need for this
+// interrupt handler.
+extern "C" void __sbe_machine_check_handler()
+{
+ asm(
+ "# Save r4 to stack, since it is going to be used by\n"
+ "# this handler\n"
+ "stwu %r1, -8(%r1)\n"
+ "stw %r4, 0(%r1)\n"
+ "# Check the MCS bits (29:31) in the ISR to determine the cause for the machine check\n"
+ "# For a data machine check, the MCS should be 0x001 to 0x011\n"
+ "mfisr %r4\n"
+ "andi. %r4, %r4, 0x0007\n"
+ "bwz %r4, __hang_forever\n"
+ "cmpwibgt %r4, 0x0003, __hang_forever\n"
+ "# The EDR contains the address that caused the machine check\n"
+ "mfedr %r4\n"
+ "srawi %r4, %r4, 16\n"
+ "# If the address is in the range 0x00000000 - 0x7f000000, we treat it as a\n"
+ "# failed scom and jump to __scom_error\n"
+ "cmplwi %r4, 0x8000\n"
+ "blt __scom_error\n"
+ "# Else, just hang here forever\n"
+ "__hang_forever:\n"
+ "b .\n"
+ "__scom_error:\n"
+ "# The srr0 contains the address of the instruction that caused the machine\n"
+ "# check (since the the interrupt is raised *before* the instruction\n"
+ "# completed execution). Since we want the code to continue with the next\n"
+ "# instruction, we increment srr0 by 4, restore r4, and rfi to branch to srr0\n"
+ "mfsrr0 %r4\n"
+ "addi %r4, %r4, 4\n"
+ "mtsrr0 %r4\n"
+ "lwz %r4, 0(%r1)\n"
+ "addi %r1, %r1, 8\n"
+ "rfi\n"
+ );
+}
+
diff --git a/src/sbefw/sbeirq.H b/src/sbefw/sbeirq.H
new file mode 100644
index 00000000..8102ce81
--- /dev/null
+++ b/src/sbefw/sbeirq.H
@@ -0,0 +1,109 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeirq.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * $file: ppe/sbe/sbefw/sbeirq.H
+ *
+ * @brief This file contains the SBE PPE Interrupt Request numbers
+ */
+
+#ifndef _SBE_IRQ_H
+#define _SBE_IRQ_H
+
+/**
+ * @brief SBE PPE IRQ numbers
+ *
+ */
+
+#define SBE_IRQ_START0 0 /* SBE Start Vector 0 */
+#define SBE_IRQ_START1 1 /* SBE Start Vector 1 */
+#define SBE_IRQ_INTR0 2 /* SBE Interrupt S0 */
+#define SBE_IRQ_INTR1 3 /* SBE Interrupt S1 */
+#define SBE_IRQ_DRTM_REQ 4 /* DRTM late launch request */
+#define SBE_IRQ_SBEFIFO_RESET 5 /* FIFO - Reset request from SE */
+#define SBE_IRQ_SBEFIFO_DATA 6 /* FIFO - Incoming Data Available */
+#define SBE_IRQ_HOST_PSU_INTR 7 /* PSU - Incoming Data Available */
+
+
+#define SBE_IRQ_RESERVED_8 8
+#define SBE_IRQ_RESERVED_9 9
+
+#define SBE_IRQ_RESERVED_10 10
+#define SBE_IRQ_RESERVED_11 11
+#define SBE_IRQ_RESERVED_12 12
+#define SBE_IRQ_RESERVED_13 13
+#define SBE_IRQ_RESERVED_14 14
+#define SBE_IRQ_RESERVED_15 15
+#define SBE_IRQ_RESERVED_16 16
+#define SBE_IRQ_RESERVED_17 17
+#define SBE_IRQ_RESERVED_18 18
+#define SBE_IRQ_RESERVED_19 19
+#define SBE_IRQ_RESERVED_20 20
+#define SBE_IRQ_RESERVED_21 21
+#define SBE_IRQ_RESERVED_22 22
+#define SBE_IRQ_RESERVED_23 23
+#define SBE_IRQ_RESERVED_24 24
+#define SBE_IRQ_RESERVED_25 25
+#define SBE_IRQ_RESERVED_26 26
+#define SBE_IRQ_RESERVED_27 27
+#define SBE_IRQ_RESERVED_28 28
+#define SBE_IRQ_RESERVED_29 29
+#define SBE_IRQ_RESERVED_30 30
+#define SBE_IRQ_RESERVED_31 31
+#define SBE_IRQ_RESERVED_32 32
+#define SBE_IRQ_RESERVED_33 33
+#define SBE_IRQ_RESERVED_34 34
+#define SBE_IRQ_RESERVED_35 35
+#define SBE_IRQ_RESERVED_36 36
+#define SBE_IRQ_RESERVED_37 37
+#define SBE_IRQ_RESERVED_38 38
+#define SBE_IRQ_RESERVED_39 39
+#define SBE_IRQ_RESERVED_40 40
+#define SBE_IRQ_RESERVED_41 41
+#define SBE_IRQ_RESERVED_42 42
+#define SBE_IRQ_RESERVED_43 43
+#define SBE_IRQ_RESERVED_44 44
+#define SBE_IRQ_RESERVED_45 45
+#define SBE_IRQ_RESERVED_46 46
+#define SBE_IRQ_RESERVED_47 47
+#define SBE_IRQ_RESERVED_48 48
+#define SBE_IRQ_RESERVED_49 49
+#define SBE_IRQ_RESERVED_50 50
+#define SBE_IRQ_RESERVED_51 51
+#define SBE_IRQ_RESERVED_52 52
+#define SBE_IRQ_RESERVED_53 53
+#define SBE_IRQ_RESERVED_54 54
+#define SBE_IRQ_RESERVED_55 55
+#define SBE_IRQ_RESERVED_56 56
+#define SBE_IRQ_RESERVED_57 57
+#define SBE_IRQ_RESERVED_58 58
+#define SBE_IRQ_RESERVED_59 59
+#define SBE_IRQ_RESERVED_60 60
+#define SBE_IRQ_RESERVED_61 61
+#define SBE_IRQ_RESERVED_62 62
+#define SBE_IRQ_RESERVED_63 63
+
+#define SBE_MACHINE_CHECK_HANDLER \
+ b __sbe_machine_check_handler
+
+#endif //_SBE_IRQ_H
diff --git a/src/sbefw/sbemain.C b/src/sbefw/sbemain.C
new file mode 100644
index 00000000..06488c14
--- /dev/null
+++ b/src/sbefw/sbemain.C
@@ -0,0 +1,352 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbemain.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/* @file: ppe/sbe/sbefw/sbemain.C
+ *
+ * @brief This file does the following
+ * - SBE Application Main entry point
+ * - PK initialization
+ * - Thread initialization
+ * - Semaphore initialization
+ * - IRQ setup
+ * - Scheduling of the threads and
+ * - Starting of the control loop code flow
+ *
+ */
+
+
+#include "sbeexeintf.H"
+#include "sbetrace.H"
+#include "sberegaccess.H"
+#include "sbestates.H"
+#include "fapi2.H" // For target init
+
+////////////////////////////////////////////////////////////////
+// @brief Global semaphores
+////////////////////////////////////////////////////////////////
+PkSemaphore g_sbeSemCmdRecv;
+PkSemaphore g_sbeSemCmdProcess;
+
+// Max defines for Semaphores
+static uint32_t MAX_SEMAPHORE_COUNT = 3;
+
+////////////////////////////////////////////////////////////////
+// @brief Stacks for Non-critical Interrupts and Threads
+////////////////////////////////////////////////////////////////
+uint8_t g_sbe_Kernel_NCInt_stack[SBE_NONCRITICAL_STACK_SIZE];
+uint8_t g_sbeCommandReceiver_stack[SBE_THREAD_CMD_RECV_STACK_SIZE];
+uint8_t g_sbeSyncCommandProcessor_stack[SBE_THREAD_SYNC_CMD_PROC_STACK_SIZE];
+uint8_t g_sbeAsyncCommandProcessor_stack[SBE_THREAD_ASYNC_CMD_PROC_STACK_SIZE];
+
+////////////////////////////////////////////////////////////////
+// @brief PkThread structure for SBE Command Receiver thread
+////////////////////////////////////////////////////////////////
+PkThread g_sbeCommandReceiver_thread;
+
+////////////////////////////////////////////////////////////////
+// @brief PkThread structure for SBE Synchronous ChipOps
+// processing thread
+////////////////////////////////////////////////////////////////
+PkThread g_sbeSyncCommandProcessor_thread;
+
+////////////////////////////////////////////////////////////////
+//// @brief PkThread structure for SBE Asynchronous ChipOps
+//// processing thread
+////////////////////////////////////////////////////////////////
+PkThread g_sbeAsyncCommandProcessor_thread;
+
+extern "C"
+{
+// These variables are declared in linker script to keep track of
+// global constructor pointer functions and sbss section.
+extern void (*ctor_start_address)() __attribute__ ((section (".rodata")));
+extern void (*ctor_end_address)() __attribute__ ((section (".rodata")));
+extern uint64_t _sbss_start __attribute__ ((section (".sbss")));
+extern uint64_t _sbss_end __attribute__ ((section (".sbss")));
+// This function will be used to do any C++ handling required before doing
+// any main job. Call to this function should get generated by
+// compiler.
+// TODO via RTC 152070
+// We are also initialising sbss section to zero this function.
+// Though it does not do any harm as of now, it is better if we use loader
+// or linker script to zero init sbss section. This way we will be future
+// garded if pk boot uses some static/global data initialised to
+// false in future.
+void __eabi()
+{
+ // Initialise sbss section
+ uint64_t *startAddr = &_sbss_start;
+ while ( startAddr != &_sbss_end )
+ {
+ *startAddr = 0;
+ startAddr++;
+ }
+
+ // Call global constructors
+ void(**ctors)() = &ctor_start_address;
+ while( ctors != &ctor_end_address)
+ {
+ (*ctors)();
+ ctors++;
+ }
+}
+} // end extern "C"
+
+////////////////////////////////////////////////////////////////
+// @brief sbeInitSems - Create the necessary semaphores
+//
+// @return PK_OK - Success
+// PK_INVALID_SEMAPHORE_AT_CREATE - Invalid PkSemaphore
+// PK_INVALID_ARGUMENT_SEMAPHORE - max_count is non-zero
+// and less than the initial_count
+////////////////////////////////////////////////////////////////
+uint32_t sbeInitSems(void)
+{
+ SBE_ENTER("sbeInitSems");
+ int l_rc = PK_OK;
+
+ do
+ {
+ l_rc = pk_semaphore_create(&g_sbeSemCmdRecv, 0, MAX_SEMAPHORE_COUNT);
+ if (l_rc)
+ {
+ break;
+ }
+ l_rc = pk_semaphore_create(&g_sbeSemCmdProcess, 0, MAX_SEMAPHORE_COUNT);
+ if (l_rc)
+ {
+ break;
+ }
+ } while (false);
+
+ if (l_rc)
+ {
+ SBE_ERROR ("pk_semaphore_create, rc=[%d]", l_rc);
+ }
+ return l_rc;
+}
+
+////////////////////////////////////////////////////////////////
+// @brief createAndResumeThreadHelper
+// - Create and resume the given thread
+//
+// @param[in/out] io_thread A pointer to an PkThread structure to initialize
+// @param[in] i_thread_routine The subroutine that implements the thread
+// @param[in/out] io_arg Private data to be passed as the argument to the
+// thread routine when it begins execution
+// @param[in] i_stack The stack space of the thread
+// @param[in] i_stack_size The size of the stack in bytes
+// @param[in] i_priority The initial priority of the thread
+//
+// @return PK_OK Successfully created and resumed the thread
+//
+// @return PK_INVALID_THREAD_AT_CREATE io_thread is null
+// @return PK_INVALID_ARGUMENT_THREAD1 i_thread_routine is null
+// @return PK_INVALID_ARGUMENT_THREAD2 i_priority is invalid
+// @return PK_INVALID_ARGUMENT_THREAD3 the stack area wraps around
+// the end of memory.
+// @return PK_STACK_OVERFLOW The stack area at thread creation
+// is smaller than the min safe size
+// @return PK_INVALID_THREAD_AT_RESUME1 io_thread is null (unlikely)
+// @return PK_INVALID_THREAD_AT_RESUME2 The thread is not active,
+// i.e. has completed or been deleted,
+// @return PK_PRIORITY_IN_USE_AT_RESUME Another thread is already
+// mapped at the priority of the thread
+////////////////////////////////////////////////////////////////
+uint32_t createAndResumeThreadHelper(PkThread *io_pThread,
+ PkThreadRoutine i_thread_routine,
+ void *io_pArg,
+ PkAddress i_stack,
+ size_t i_stack_size,
+ sbeThreadPriorities i_priority)
+{
+ int l_rc = PK_OK;
+
+ // Thread creation
+ l_rc = pk_thread_create(io_pThread,
+ i_thread_routine,
+ io_pArg,
+ i_stack,
+ i_stack_size,
+ (PkThreadPriority)i_priority);
+ if(l_rc == PK_OK)
+ {
+ // resume the thread once created
+ l_rc = pk_thread_resume(io_pThread);
+ }
+
+ // Check for errors creating or resuming the thread
+ if(l_rc != PK_OK)
+ {
+ SBE_ERROR ("Failure creating/resuming thread, rc=[%d]", l_rc);
+ }
+
+ return l_rc;
+}
+
+////////////////////////////////////////////////////////////////
+// @brief sbeInitThreads
+// Create the resume all the firmware threads
+//
+// @return See createAndResumeThreadHelper for more details
+////////////////////////////////////////////////////////////////
+int sbeInitThreads(void)
+{
+ // Locals
+ uint32_t l_rc = PK_OK;
+
+ do
+ {
+ // Initialize Command receiver thread
+ l_rc = createAndResumeThreadHelper(&g_sbeCommandReceiver_thread,
+ sbeCommandReceiver_routine,
+ (void *)0,
+ (PkAddress)g_sbeCommandReceiver_stack,
+ SBE_THREAD_CMD_RECV_STACK_SIZE,
+ THREAD_PRIORITY_5);
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Initialize Synchronous Command Processor thread
+ l_rc = createAndResumeThreadHelper(&g_sbeSyncCommandProcessor_thread,
+ sbeSyncCommandProcessor_routine,
+ (void *)0,
+ (PkAddress)g_sbeSyncCommandProcessor_stack,
+ SBE_THREAD_SYNC_CMD_PROC_STACK_SIZE,
+ THREAD_PRIORITY_7);
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Initialize Asynchronous Command Processor thread
+ l_rc = createAndResumeThreadHelper(&g_sbeAsyncCommandProcessor_thread,
+ sbeAsyncCommandProcessor_routine,
+ (void *)0,
+ (PkAddress)g_sbeAsyncCommandProcessor_stack,
+ SBE_THREAD_ASYNC_CMD_PROC_STACK_SIZE,
+ THREAD_PRIORITY_6);
+ if (l_rc)
+ {
+ break;
+ }
+ } while (false);
+
+ // If there are any errors initializing the threads
+ if( l_rc )
+ {
+ SBE_ERROR ("Error Initializing a thread, rc=[%d]", l_rc);
+ }
+
+ return l_rc;
+}
+
+////////////////////////////////////////////////////////////////
+// @brief - main : SBE Application main
+////////////////////////////////////////////////////////////////
+uint32_t main(int argc, char **argv)
+{
+ #define SBE_FUNC "main "
+ SBE_ENTER(SBE_FUNC);
+ int l_rc = 0;
+
+ // @TODO via RTC : 128818
+ // Explore on reclaiming the stack
+ // used by this Initialization code
+
+ do
+ {
+ // initializes kernel data -
+ // stack, threads, timebase, timers, etc.
+ l_rc = pk_initialize((PkAddress)g_sbe_Kernel_NCInt_stack,
+ SBE_NONCRITICAL_STACK_SIZE,
+ 0,
+ 500000000); // @TODO via RTC : 128819
+ // Need to obtain at Runtime, a new attribute?
+ if (l_rc)
+ {
+ break;
+ }
+
+ SBE_INFO("Completed PK init");
+
+ // Initialize the semaphores
+ l_rc = sbeInitSems();
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Initialize SBE control loop threads
+ l_rc = sbeInitThreads();
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Setup SBE PPE IRQs
+ l_rc = sbeIRQSetup();
+ if (l_rc)
+ {
+ break;
+ }
+
+ // TODO via RTC 126146.
+ // Check if we should call plat_TargetsInit in some other thread.
+ // We may want to keep only PK init in main and can move
+ // plat init to some other thread. Only if this is required by more
+ // than one thread and there can be some race condition, we will
+ // keep it here before starting other threads.
+ fapi2::ReturnCode fapiRc = fapi2::plat_TargetsInit();
+ if( fapiRc != fapi2::FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC"plat_TargetsInit failed");
+ (void)SbeRegAccess::theSbeRegAccess().
+ stateTransition(SBE_FAILURE_EVENT);
+ // Hard Reset SBE to recover
+ break;
+ }
+
+ if(SbeRegAccess::theSbeRegAccess().init())
+ {
+ SBE_ERROR(SBE_FUNC"Failed to initialize SbeRegAccess");
+ // init failure could mean the below will fail too, but attempt it
+ // anyway
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_FAILURE_EVENT);
+ // Hard Reset SBE to recover
+ break;
+ }
+
+ // Start running the highest priority thread.
+ // This function never returns
+ pk_start_threads();
+
+ } while (false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+}
diff --git a/src/sbefw/sberegaccess.C b/src/sbefw/sberegaccess.C
new file mode 100644
index 00000000..71540e56
--- /dev/null
+++ b/src/sbefw/sberegaccess.C
@@ -0,0 +1,331 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sberegaccess.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sberegaccess.C
+ *
+ * @brief This file contains interfaces to get/set FW flags either in the
+ * scratch registers and/or the FW attributes.
+ */
+
+#include "sberegaccess.H"
+#include "sbetrace.H"
+#include "fapi2.H"
+#include <ppe42_scom.h>
+#include <p9_perv_scom_addresses.H>
+
+using namespace fapi2;
+
+// Struct to Map Current State - Event - Final State Transition
+typedef struct stateTransitionStr
+{
+ uint16_t currState:4;
+ uint16_t event:4;
+ uint16_t finalState:4;
+ uint16_t reserved:4;
+} stateTransitionStr_t;
+
+// Start and End point of Event Transition in stateTransMap Table
+typedef struct stateEventRangeStr
+{
+ uint16_t start:8;
+ uint16_t end:8;
+}stateEventRangeStr_t;
+
+// Entry Point and End point to the StateTransition Map for a State
+// It is sequenced as per the sbeState enum, Don't change the sequence
+// of states. Events are incremented w.r.t previous event.
+static const stateEventRangeStr_t eventRangePerState[SBE_MAX_STATE] =
+{
+ {SBE_STATE_UNKNOWN_ENTRY_TO_MAP, SBE_STATE_UNKNOWN_MAX_EVENT},
+ {SBE_STATE_FFDC_COLLECT_ENTRY_TO_MAP, SBE_STATE_FFDC_COLLECT_MAX_EVENT},
+ {SBE_STATE_IPLING_ENTRY_TO_MAP, SBE_STATE_IPLING_MAX_EVENT},
+ {SBE_STATE_ISTEP_ENTRY_TO_MAP, SBE_STATE_ISTEP_MAX_EVENT},
+ {SBE_STATE_RUNTIME_ENTRY_TO_MAP, SBE_STATE_RUNTIME_MAX_EVENT},
+ {SBE_STATE_MPIPL_ENTRY_TO_MAP, SBE_STATE_MPIPL_MAX_EVENT},
+ {SBE_STATE_DMT_ENTRY_TO_MAP, SBE_STATE_DMT_MAX_EVENT},
+ {SBE_STATE_DUMP_ENTRY_TO_MAP, SBE_STATE_DUMP_MAX_EVENT},
+ {SBE_STATE_FAILURE_ENTRY_TO_MAP, SBE_STATE_FAILURE_MAX_EVENT},
+ {SBE_STATE_QUIESCE_ENTRY_TO_MAP, SBE_STATE_QUIESCE_MAX_EVENT},
+ {SBE_STATE_ABORT_ENTRY_TO_MAP, SBE_STATE_ABORT_MAX_EVENT},
+};
+
+// Map to connect the current State with an event along with the final state
+// transition. It is sequenced according to the sbeState enums, Don't change the
+// sequence of states.
+static const stateTransitionStr_t stateTransMap[SBE_MAX_TRANSITIONS] = {
+ {SBE_STATE_UNKNOWN, SBE_FAILURE_EVENT, SBE_STATE_FAILURE},
+ {SBE_STATE_UNKNOWN, SBE_RUNTIME_EVENT, SBE_STATE_RUNTIME},
+ {SBE_STATE_UNKNOWN, SBE_ISTEP_EVENT, SBE_STATE_ISTEP},
+ {SBE_STATE_UNKNOWN, SBE_PLCK_EVENT, SBE_STATE_IPLING},
+ {SBE_STATE_UNKNOWN, SBE_FFDC_COLLECT_EVENT, SBE_STATE_FFDC_COLLECT},
+ {SBE_STATE_FFDC_COLLECT, SBE_CONTINUE_BOOT_PLCK_EVENT, SBE_STATE_IPLING},
+ {SBE_STATE_FFDC_COLLECT, SBE_CONTINUE_BOOT_RUNTIME_EVENT, SBE_STATE_RUNTIME},
+ {SBE_STATE_FFDC_COLLECT, SBE_ISTEP_EVENT, SBE_STATE_ISTEP},
+ {SBE_STATE_FFDC_COLLECT, SBE_FAILURE_EVENT, SBE_STATE_DUMP},
+ {SBE_STATE_IPLING, SBE_RUNTIME_EVENT, SBE_STATE_RUNTIME},
+ {SBE_STATE_IPLING, SBE_DUMP_FAILURE_EVENT, SBE_STATE_DUMP},
+ {SBE_STATE_IPLING, SBE_FAILURE_EVENT, SBE_STATE_FAILURE},
+ {SBE_STATE_IPLING, SBE_ABORT_EVENT, SBE_STATE_ABORT},
+ {SBE_STATE_ISTEP, SBE_RUNTIME_EVENT, SBE_STATE_RUNTIME},
+ {SBE_STATE_ISTEP, SBE_ABORT_EVENT, SBE_STATE_ABORT},
+ {SBE_STATE_ISTEP, SBE_FAILURE_EVENT, SBE_STATE_FAILURE},
+ {SBE_STATE_RUNTIME, SBE_DUMP_FAILURE_EVENT, SBE_STATE_DUMP},
+ {SBE_STATE_RUNTIME, SBE_ENTER_MPIPL_EVENT, SBE_STATE_MPIPL},
+ {SBE_STATE_RUNTIME, SBE_DMT_ENTER_EVENT, SBE_STATE_DMT},
+ {SBE_STATE_RUNTIME, SBE_FAILURE_EVENT, SBE_STATE_FAILURE},
+ {SBE_STATE_MPIPL, SBE_CONTINUE_MPIPL_EVENT, SBE_STATE_RUNTIME},
+ {SBE_STATE_MPIPL, SBE_DUMP_FAILURE_EVENT, SBE_STATE_DUMP},
+ {SBE_STATE_DMT, SBE_DMT_COMP_EVENT, SBE_STATE_RUNTIME},
+};
+
+/**
+ * @brief Initizlize the class
+ *
+ * @return An RC indicating success/failure
+ */
+
+void SbeRegAccess::stateTransition(const sbeEvent &i_event)
+{
+ #define SBE_FUNC "SbeRegAccess::stateTransition "
+ //Fetch Current State
+ uint32_t l_state = (uint32_t)getSbeState();
+ uint8_t l_startCnt = eventRangePerState[l_state].start;
+ SBE_INFO(SBE_FUNC "Event Received %d CurrState 0x%08X StartCnt%d EndCnt%d",
+ i_event, l_state, l_startCnt, eventRangePerState[l_state].end);
+ // Fetch the final State from the Map
+ while(l_startCnt <
+ (eventRangePerState[l_state].end + eventRangePerState[l_state].start))
+ {
+ if(stateTransMap[l_startCnt].event == i_event)
+ {
+ SBE_INFO(SBE_FUNC "Updating State as %d",
+ (sbeState)stateTransMap[l_startCnt].finalState);
+ updateSbeState((sbeState)stateTransMap[l_startCnt].finalState);
+ break;
+ }
+ else
+ ++l_startCnt;
+ }
+ #undef SBE_FUNC
+}
+
+uint32_t SbeRegAccess::init()
+{
+ #define SBE_FUNC "SbeRegAccess::SbeRegAccess "
+ static bool l_initDone = false;
+ uint32_t l_rc = 0;
+ uint64_t l_mbx8 = 0;
+ do
+ {
+ if(l_initDone)
+ {
+ break;
+ }
+ // Read SBE messaging register into iv_messagingReg
+ l_rc = getscom_abs(PERV_SB_MSG_SCOM, &iv_messagingReg);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading sbe messaging reg., RC: 0x%08X. ",
+ l_rc);
+ break;
+ }
+ // Read Mailbox register 8 to check if the mailbox registers 3 and 6 are
+ // valid
+ l_rc = getscom_abs(PERV_SCRATCH_REGISTER_8_SCOM, &l_mbx8);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading mailbox reg 7, RC: 0x%08X. ",
+ l_rc);
+ break;
+ }
+ if(l_mbx8 & SBE_MBX8_MBX3_VALID_MASK)
+ {
+ // Read MBX3
+ l_rc = getscom_abs(PERV_SCRATCH_REGISTER_3_SCOM, &iv_mbx3);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading mailbox reg 3, RC: 0x%08X. ",
+ l_rc);
+ break;
+ }
+ }
+ else
+ {
+ // Need to read the values off the attributes
+ uint32_t l_attr = 0;
+ FAPI_ATTR_GET(ATTR_BOOT_FLAGS, Target<TARGET_TYPE_SYSTEM>(),
+ l_attr);
+ iv_mbx3 = ((uint64_t) l_attr ) << 32;
+ }
+ if(l_mbx8 & SBE_MBX8_MBX6_VALID_MASK)
+ {
+ // Read MBX6
+ l_rc = getscom_abs(PERV_SCRATCH_REGISTER_6_SCOM, &iv_mbx6);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading mailbox reg 6, RC: 0x%08X. "
+ l_rc);
+ break;
+ }
+ }
+ // If the master/slave bit is 0 (either default or read from mbx6),
+ // check the C4 board pin to determine role
+ if(0 == iv_isSlave)
+ {
+ uint64_t l_sbeDevIdReg = 0;
+ // Read device ID register
+ l_rc = getscom_abs(PERV_DEVICE_ID_REG, &l_sbeDevIdReg);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading device id reg, RC: 0x%08X. "
+ l_rc);
+ break;
+ }
+ iv_isSlave = l_sbeDevIdReg & SBE_DEV_ID_C4_PIN_MASK;
+ SBE_INFO(SBE_FUNC"Overriding master/slave with data read from "
+ "C4 pin: HI: 0x%08X, LO: 0x%08X",
+ (uint32_t)(l_sbeDevIdReg >> 32),
+ (uint32_t)(l_sbeDevIdReg & 0xFFFFFFFF));
+ }
+ } while(false);
+
+ SBE_INFO(SBE_FUNC"Read mailbox registers: mbx8: 0x%08X, mbx3: 0x%08X, "
+ "mbx6: 0x%08X", (uint32_t)(l_mbx8 >> 32),
+ (uint32_t)(iv_mbx3 >> 32), (uint32_t)(iv_mbx6 >> 32));
+ l_initDone = true;
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/**
+ * @brief Update the SBE states into the SBE messaging register. The
+ * function does a read-modify-write, so any bits other than the state
+ * bits are preserved. The current state of the register is set to
+ * i_state, whereas the old current state is copied to previous state
+ *
+ * @param [in] i_state The current SBE state
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+uint32_t SbeRegAccess::updateSbeState(const sbeState &i_state)
+{
+ #define SBE_FUNC "SbeRegAccess::updateSbeState "
+ uint32_t l_rc = 0;
+
+ iv_prevState = iv_currState;
+ iv_currState = i_state;
+ l_rc = putscom_abs(PERV_SB_MSG_SCOM, iv_messagingReg);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed to update state to messaging "
+ "register. RC: 0x%08X", l_rc);
+ }
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/**
+ * @brief Update the SBE IPL steps into the SBE messaging register. The
+ * function does a read-modify-write, so any bits other than the IPL
+ * steps are retianed
+ *
+ * @param [in] i_major IPL major step number
+ * @param [in] i_minor IPL minor step number
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+uint32_t SbeRegAccess::updateSbeStep(const uint8_t i_major,
+ const uint8_t i_minor)
+{
+ #define SBE_FUNC "SbeRegAccess::updateSbeStep "
+ uint32_t l_rc = 0;
+
+ iv_majorStep = i_major;
+ iv_minorStep = i_minor;
+
+ l_rc = putscom_abs(PERV_SB_MSG_SCOM, iv_messagingReg);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed to update SBE step to messaging "
+ "register. RC: 0x%08X", l_rc);
+ }
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/**
+ * @brief Set the SBE ready bit into the SBE messaging register
+ * (meaning that SBE control loop is initialized) The function does a
+ * read-modify-write, so any bits other than the SBE ready bit remain
+ * unchanged.
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+uint32_t SbeRegAccess::setSbeReady()
+{
+ #define SBE_FUNC "SbeRegAccess::setSbeReady "
+ uint32_t l_rc = 0;
+
+ iv_sbeBooted = true;
+ l_rc = putscom_abs(PERV_SB_MSG_SCOM, iv_messagingReg);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed to update SBE ready state to "
+ "messaging register. RC: 0x%08X", l_rc);
+ }
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
+/**
+ * @brief Set the MPIPL mode bit into the mailbox scratch reg. 3
+ * The function does a read-modify-write, so any bits other than the
+ * SBE ready bit remain unchanged.
+ *
+ * @param i_set [in] Whether to set or clear the MPIPL flag
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+uint32_t SbeRegAccess::setMpIplMode(const bool i_set)
+{
+ #define SBE_FUNC "SbeRegAccess::setMpIplMode"
+ uint32_t l_rc = 0;
+ uint8_t l_set = i_set;
+ iv_mpiplMode = i_set;
+ FAPI_ATTR_SET(ATTR_IS_MPIPL, Target<TARGET_TYPE_SYSTEM>(), l_set);
+ l_rc = putscom_abs(PERV_SCRATCH_REGISTER_3_SCOM, iv_mbx3);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed to set/clear MPIPL flag in "
+ "mbx reg. 3. RC: 0x%08X", l_rc);
+ }
+ return l_rc;
+ #undef SBE_FUNC
+}
+
diff --git a/src/sbefw/sberegaccess.H b/src/sbefw/sberegaccess.H
new file mode 100644
index 00000000..84e2c87e
--- /dev/null
+++ b/src/sbefw/sberegaccess.H
@@ -0,0 +1,266 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sberegaccess.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sberegaccess.H
+ *
+ * @brief This file contains interfaces to get/set FW flags either in the
+ * scratch registers and/or the FW attributes.
+ */
+
+#ifndef __SBEFW_SBEREGACCESS_H
+#define __SBEFW_SBEREGACCESS_H
+
+#include <stdint.h>
+#include "sbestates.H"
+#include "sbeevents.H"
+
+/**
+ * @brief Utility singleton that SBEFW can use to read write various scratch
+ * registers/FW attributes
+ * TODO: via RTC ??????: Need to change the read of scratch registers to FAPI
+ * attribute accesses once we have the attributes defined in the HWP code.
+ */
+class SbeRegAccess
+{
+ public:
+ // Disable copy construction and assignment operators
+ SbeRegAccess(const SbeRegAccess&) = delete;
+ SbeRegAccess& operator=(const SbeRegAccess&) = delete;
+
+ /**
+ * @brief Returns the instance of this class
+ *
+ * @return A reference to SbeRegAccess
+ *
+ */
+ static SbeRegAccess& theSbeRegAccess()
+ {
+ static SbeRegAccess iv_instance;
+ return iv_instance;
+ }
+
+ /**
+ * @brief Initializes the class for use
+ *
+ * @return An RC indicating success/failure
+ *
+ */
+ uint32_t init();
+
+ /**
+ * @brief Update the SBE states into the SBE messaging register. The
+ * function does a read-modify-write, so any bits other than the state
+ * bits are preserved. The current state of the register is set to
+ * i_state, whereas the old current state is copied to previous state
+ *
+ * @param [in] i_state The current SBE state
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+ uint32_t updateSbeState(const sbeState &i_state);
+
+ /**
+ * @brief Update the SBE IPL steps into the SBE messaging register. The
+ * function does a read-modify-write, so any bits other than the IPL
+ * steps are retianed
+ *
+ * @param [in] i_major IPL major step number
+ * @param [in] i_minor IPL minor step number
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+ uint32_t updateSbeStep(const uint8_t i_major, const uint8_t i_minor);
+
+ /**
+ * @brief Set the SBE ready bit into the SBE messaging register
+ * (meaning that SBE control loop is initialized) The function does a
+ * read-modify-write, so any bits other than the SBE ready bit remain
+ * unchanged.
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+ uint32_t setSbeReady();
+
+ /**
+ * @brief Set the MPIPL mode bit into the mailbox scratch reg. 3
+ * The function does a read-modify-write, so any bits other than the
+ * SBE ready bit remain unchanged. It also updates the attribute
+ * ATTR_MPIPL
+ *
+ * @param i_set [in] true == set, false == clear
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+ uint32_t setMpIplMode(const bool i_set);
+
+ /**
+ * @brief Check if we are on an FSP attached
+ *
+ * @return true if FSP attached system, false otherwise
+ *
+ */
+ inline bool isFspSystem() const
+ {
+ return iv_fspAttached;
+ }
+
+ /**
+ * @brief Check if we are in ISTEP IPL mode
+ *
+ * @return true if in istep mode, false otherwise
+ *
+ */
+ inline bool isIstepMode() const
+ {
+ return iv_istepMode;
+ }
+
+ /**
+ * @brief Check if SBE should directly go to runtime state
+ *
+ * @return true if SBE should go directly to runtime state,
+ * false otherwise
+ *
+ */
+ inline bool isDestBitRuntime() const
+ {
+ return iv_sbeDestRuntime;
+ }
+
+ /**
+ * @brief Check if SBE should collect FFDC
+ *
+ * @return true if in istep mode, false otherwise
+ *
+ */
+ inline bool isCollectFFDCSet() const
+ {
+ return iv_collectFFDC;
+ }
+
+ /**
+ * @brief Check if SBE should send internal FFDC for any chip op
+ * failures as a part of the response
+ *
+ * @return true if in istep mode, false otherwise
+ *
+ */
+ inline bool isSendInternalFFDCSet() const
+ {
+ return iv_sendFFDC;
+ }
+
+ /**
+ * @brief Check if SBE is slave/master
+ *
+ * @return true if SBE is slave, false if master
+ *
+ */
+ inline bool isSbeSlave() const
+ {
+ return iv_isSlave;
+ }
+
+ /**
+ * @brief Get the SBE current State
+ *
+ * @return SBE current State, sbeState enum
+ *
+ */
+ uint64_t getSbeState() const
+ {
+ return iv_currState;
+ }
+
+ /**
+ * @brief Update the SBE State as per the transition event
+ *
+ * @param [in] i_event Transition Event
+ */
+ void stateTransition(const sbeEvent &i_event);
+
+ private:
+
+ /**
+ * @brief Constructor
+ */
+ SbeRegAccess() : iv_mbx3(0), iv_mbx6(0), iv_messagingReg(0)
+ {}
+
+ union
+ {
+ struct
+ {
+ uint64_t iv_istepMode : 1;
+ uint64_t iv_sbeDestRuntime : 1;
+ uint64_t iv_mpiplMode : 1;
+ uint64_t iv_fspAttached : 1;
+ uint64_t iv_collectFFDC : 1;
+ uint64_t iv_sendFFDC : 1;
+ uint64_t iv_mbx3DontCare : 26;
+ uint64_t iv_mbx3Unused : 32;
+ };
+ uint64_t iv_mbx3;
+ };
+
+ union
+ {
+ struct
+ {
+ uint64_t iv_mbx6DontCare : 24;
+ uint64_t iv_isSlave : 1;
+ uint64_t iv_mbx6DontCare2 : 7;
+ uint64_t iv_mbx6Unused : 32;
+ };
+ uint64_t iv_mbx6;
+ };
+
+ union
+ {
+ struct
+ {
+ uint64_t iv_sbeBooted : 1;
+ uint64_t iv_reserved1 : 3;
+ uint64_t iv_prevState : 4;
+ uint64_t iv_currState : 4;
+ uint64_t iv_majorStep : 4;
+ uint64_t iv_minorStep : 8;
+ uint64_t iv_reserved2 : 8;
+ uint64_t iv_unused : 32;
+ };
+ uint64_t iv_messagingReg;
+ };
+
+ // Bit masks defining bits in the above registers that the SBE is
+ // interested in
+ static const uint64_t SBE_MBX8_MBX3_VALID_MASK = 0x2000000000000000ULL;
+ static const uint64_t SBE_MBX8_MBX6_VALID_MASK = 0x0400000000000000ULL;
+ static const uint64_t SBE_DEV_ID_C4_PIN_MASK = 0x0000000000800000ULL;
+};
+#endif //__SBEFW_SBEREGACCESS_H
+
diff --git a/src/sbefw/sbescom.C b/src/sbefw/sbescom.C
new file mode 100644
index 00000000..9a2fc38c
--- /dev/null
+++ b/src/sbefw/sbescom.C
@@ -0,0 +1,198 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbescom.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include <stdint.h>
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "ppe42_scom.h"
+
+/**
+ * @brief Indirect SCOM Status
+ */
+union IndirectScom_t
+{
+ uint64_t data64;
+ struct
+ {
+ uint64_t :12; //0:11
+ uint64_t addr:20; //12:31
+ uint64_t done:1; //32
+ uint64_t piberr:3; //33:35
+ uint64_t userstat:4; //36:39
+ uint64_t :8; //40:47
+ uint64_t data:16; //48:63
+ };
+
+};
+
+// Wait time slice to check indirect scom status register
+static const uint32_t SBE_INDIRECT_SCOM_WAIT_TIME_NS = 10000;
+// Indirect scom timeout
+static const uint32_t MAX_INDSCOM_TIMEOUT_NS = 100000; //0.1 ns
+
+static const uint64_t DIRECT_SCOM_ADDR_MASK = 0x8000000000000000;
+static const uint64_t INDIRECT_SCOM_NEW_ADDR_MASK = 0x9000000000000000;
+
+// Scom types
+enum sbeScomType
+{
+ SBE_SCOM_TYPE_DIRECT = 0, // Direct scom
+ SBE_SCOM_TYPE_INDIRECT1 = 1, // Indirect scom. Old form
+ SBE_SCOM_TYPE_INDIRECT_2 = 2, // Indirect scom. New form
+};
+
+uint32_t checkIndirectAndDoScom( const bool i_isRead,
+ const uint64_t i_addr,
+ uint64_t & io_data,
+ uint32_t & o_pcbPibStatus )
+{
+
+ #define SBE_FUNC " checkIndirectAndDoScom "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t elapsedIndScomTimeNs = 0;
+ uint64_t tempBuffer = io_data;
+ sbeScomType scomType = SBE_SCOM_TYPE_DIRECT;
+ do
+ {
+ // If the indirect scom bit is 0, then doing a regular scom
+ if( (i_addr & DIRECT_SCOM_ADDR_MASK) == 0)
+ {
+ SBE_INFO(SBE_FUNC "Performing Direct scom");
+ if( i_isRead )
+ {
+ o_pcbPibStatus = getscom_abs ( (uint32_t)i_addr,
+ & io_data);
+ }
+ else
+ {
+ o_pcbPibStatus = putscom_abs ( (uint32_t)i_addr,
+ io_data);
+ }
+ break;
+ }
+ // We are performing an indirect scom.
+ if( ( i_addr & INDIRECT_SCOM_NEW_ADDR_MASK ) ==
+ INDIRECT_SCOM_NEW_ADDR_MASK )
+ {
+ scomType = SBE_SCOM_TYPE_INDIRECT_2;
+ if( i_isRead )
+ {
+ // Not allowed write on new format.
+ SBE_ERROR(SBE_FUNC "Read not allowed in new form");
+ l_rc = SBE_SEC_INVALID_ADDRESS_PASSED;
+ break;
+ }
+ // Zero out the indirect address location.. leave the 52bits of data
+ // Get the 12bit indirect scom address
+ // OR in the 20bit indirect address
+ tempBuffer = ( tempBuffer & 0x000FFFFFFFFFFFFF ) |
+ ( ( i_addr & 0x00000FFF00000000) << 20 );
+ }
+ else
+ {
+ scomType = SBE_SCOM_TYPE_INDIRECT1;
+ // Zero out the indirect address location.. leave the 16bits of data
+ // Get the 20bit indirect scom address
+ // OR in the 20bit indirect address
+ tempBuffer = ( tempBuffer & 0x000000000000FFFF) |
+ ( i_addr & 0x000FFFFF00000000 );
+ }
+
+ SBE_INFO(SBE_FUNC "Performing Indirect scom. Type :%u", scomType);
+
+ // zero out the indirect address from the buffer..
+ // bit 0-31 - indirect area..
+ // bit 32 - always 0
+ // bit 33-47 - bcast/chipletID/port
+ // bit 48-63 - local addr
+ uint64_t tempAddr = i_addr & 0x000000007FFFFFFF;
+
+ // If we are doing a read. We need to do a write first..
+ if( i_isRead)
+ {
+ // turn the read bit on.
+ tempBuffer = tempBuffer | 0x8000000000000000;
+ }
+ else //write
+ {
+ // Turn the read bit off.
+ tempBuffer = tempBuffer & 0x7FFFFFFFFFFFFFFF;
+
+ } // end of write
+
+ // perform write before the read with the new
+ // IO_buffer with the imbedded indirect scom addr.
+ o_pcbPibStatus = putscom_abs ( tempAddr, tempBuffer);
+
+ if( ( o_pcbPibStatus ) || ( scomType == SBE_SCOM_TYPE_INDIRECT_2 ))
+ {
+ break;
+ }
+
+ // Need to check loop on read until we see done, error,
+ // or we timeout
+ IndirectScom_t scomout;
+ do
+ {
+ // Now perform the op requested using the passed in
+ // IO_Buffer to pass the read data back to caller.
+ o_pcbPibStatus = getscom_abs ( tempAddr, &(scomout.data64));
+
+ if( o_pcbPibStatus ) break;
+ // if bit 32 is on indicating a complete bit
+ // or we saw an error, then we're done
+ if (scomout.piberr)
+ {
+
+ SBE_ERROR(SBE_FUNC "pib error reading status register");
+ o_pcbPibStatus = scomout.piberr;
+ break;
+ }
+ if (scomout.done )
+ {
+ io_data = scomout.data;
+ break;
+ }
+
+ pk_sleep(PK_NANOSECONDS(SBE_INDIRECT_SCOM_WAIT_TIME_NS));
+ elapsedIndScomTimeNs += SBE_INDIRECT_SCOM_WAIT_TIME_NS;
+
+ }while ( elapsedIndScomTimeNs <= MAX_INDSCOM_TIMEOUT_NS);
+
+ if( o_pcbPibStatus ) break;
+ if( ! scomout.done)
+ {
+ SBE_ERROR(SBE_FUNC "Indirect scom timeout");
+ l_rc = SBE_SEC_HW_OP_TIMEOUT;
+ break;
+ }
+
+ }while(0);
+
+ if (o_pcbPibStatus ) l_rc = SBE_SEC_PCB_PIB_ERR;
+
+ SBE_DEBUG(SBE_FUNC "o_pcbPibStatus:%u l_rc:0x%08X", o_pcbPibStatus, l_rc);
+ return l_rc;
+}
+
diff --git a/src/sbefw/sbescom.H b/src/sbefw/sbescom.H
new file mode 100644
index 00000000..3809ba10
--- /dev/null
+++ b/src/sbefw/sbescom.H
@@ -0,0 +1,38 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbescom.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/**
+ * @brief check if scom address is Indirect scom and perform scom
+ *
+ * @param[in] i_isRead True if read operation, false otherwise
+ * @param[in] i_addr scom addess
+ * @param[in] io_data data for scom operation. For read, it is output operand.
+ * @param[in] o_pcbPibStatus pcbpib status
+ *
+ * @return seconday error code.
+ */
+uint32_t checkIndirectAndDoScom( const bool i_isRead,
+ const uint64_t i_addr,
+ uint64_t & io_data,
+ uint32_t & o_pcbPibStatus );
diff --git a/src/sbefw/sbestates.H b/src/sbefw/sbestates.H
new file mode 100644
index 00000000..6acaba4d
--- /dev/null
+++ b/src/sbefw/sbestates.H
@@ -0,0 +1,67 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbestates.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/*
+ * @file: ppe/sbe/sbefw/sbestates.H
+ *
+ * @brief This file contains interfaces pertaining to SBE state/role management
+ *
+ */
+
+#ifndef __SBEFW_SBESTATES_H
+#define __SBEFW_SBESTATES_H
+
+/**
+ * @brief An enumeration of all SBE states
+ *
+ */
+enum sbeState
+{
+ SBE_STATE_UNKNOWN = 0x0, // Unkown, initial state
+ SBE_STATE_FFDC_COLLECT = 0x1, // Waiting for FFDC collection after a reset
+ SBE_STATE_IPLING = 0x2, // IPL'ing - autonomous mode (transient)
+ SBE_STATE_ISTEP = 0x3, // ISTEP - Running IPL by steps (transient)
+ SBE_STATE_RUNTIME = 0x4, // SBE Runtime
+ SBE_STATE_MPIPL = 0x5, // MPIPL
+ SBE_STATE_DMT = 0x6, // Dead Man Timer State (transient)
+ SBE_STATE_DUMP = 0x7, // Dumping
+ SBE_STATE_FAILURE = 0x8, // Internal SBE failure
+ SBE_STATE_QUIESCE = 0x9, // Final state - needs SBE reset to get out
+ SBE_STATE_ABORT = 0xA, // SBE was asked to abort - need reset to get out
+
+ // Max States, Always keep it at the last of the enum and sequential
+ SBE_MAX_STATE = 0xB,
+ // Don't count this in the state, just to intialize the state variables
+ SBE_INVALID_STATE = 0xF,
+};
+
+enum sbeRole
+{
+ SBE_ROLE_MASTER = 0,
+ SBE_ROLE_SLAVE = 1
+};
+
+extern sbeRole g_sbeRole;
+
+#endif //__SBEFW_SBESTATES_H
+
diff --git a/src/sbefw/sbetrace.H b/src/sbefw/sbetrace.H
new file mode 100644
index 00000000..1d7df7e4
--- /dev/null
+++ b/src/sbefw/sbetrace.H
@@ -0,0 +1,75 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbetrace.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SBEFW_SBE_TRACE_H
+#define __SBEFW_SBE_TRACE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "pk_api.h"
+#include "trac_interface.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#define SBE_ENTER_MRK ">>"
+#define SBE_EXIT_MRK "<<"
+#define SBE_ERR_MRK "E>"
+#define SBE_INF_MRK "I>"
+#define SBE_DEBUG_MRK "D>"
+
+#define SBE_ERROR(args...)
+#define SBE_INFO(args...)
+#define SBE_ENTER(args...)
+#define SBE_EXIT(args...)
+#define SBE_DEBUG(args...)
+
+// Levels of logging
+// 0 - No tracing
+// 1 - Error
+// 2 - Error, info
+// 3 - Error, info, entry/exit
+// 4 - Error, info, entry/exit, debug
+#if (SBE_TRACE_LEVEL >= 1)
+#undef SBE_ERROR
+#define SBE_ERROR(args...) PK_TRACE(SBE_ERR_MRK"" args)
+#endif
+#if (SBE_TRACE_LEVEL >= 2)
+#undef SBE_INFO
+#define SBE_INFO(args...) PK_TRACE(SBE_INF_MRK"" args)
+#endif
+#if (SBE_TRACE_LEVEL >= 3)
+#undef SBE_ENTER
+#undef SBE_EXIT
+#define SBE_ENTER(args...) PK_TRACE(SBE_ENTER_MRK"" args)
+#define SBE_EXIT(args...) PK_TRACE(SBE_EXIT_MRK"" args)
+#endif
+#if (SBE_TRACE_LEVEL >= 4)
+#undef SBE_DEBUG
+#define SBE_DEBUG(args...) PK_TRACE(SBE_DEBUG_MRK"" args)
+#endif
+#define SBE_TRACE(args...) PK_TRACE(args)
+#endif // __SBEFW_SBE_TRACE_H
diff --git a/src/sbefw/sbeutil.H b/src/sbefw/sbeutil.H
new file mode 100644
index 00000000..07fc6b7f
--- /dev/null
+++ b/src/sbefw/sbeutil.H
@@ -0,0 +1,81 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeutil.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef SBE_UTIL_H
+#define SBE_UTIL_H
+#include "pk.h"
+#include "pk_api.h"
+
+#define MASK_ZERO_L32B_UINT64(x) ((x) & 0xFFFFFFFF00000000)
+#define MASK_ZERO_H32B_UINT64(x) ((x) & 0x00000000FFFFFFFF)
+#define SHIFT_RIGHT(x, bits) ((x) >> bits)
+
+// Macros Defined for Internal RC Check, Break if Error
+#define CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc) \
+if ((l_rc) != SBE_SEC_OPERATION_SUCCESSFUL) \
+{ \
+ break; \
+} \
+
+void sbeHandleFifoResponse (const uint32_t i_rc);
+
+void sbeHandlePsuResponse (const uint32_t i_rc);
+
+namespace SBE
+{
+
+ // Currently PK does not define start range for app
+ // specifc panic code as enum. It is implicit understanding
+ // through code comments. Expectation is 0x1cxx range is for
+ // non-pk code.
+ static const uint32_t PK_APP_OFFSET_SBE_START = 0x1c00;
+ enum
+ {
+ // For defining new panic codes refer to pk/ppe42/pk_panic_codes.h
+ PANIC_ASSERT = PK_APP_OFFSET_SBE_START
+ };
+
+ /*@brief - Get higher 32bit number from uint64
+ *
+ * @param[in] - i_lWord - 64bit long word
+ *
+ * @return - uint32_t word
+ */
+ inline uint32_t higher32BWord(uint64_t i_lWord)
+ {
+ return (uint32_t)(SHIFT_RIGHT(MASK_ZERO_L32B_UINT64(i_lWord), 32));
+ }
+
+ /*@brief - Get lower 32bit number from uint64
+ *
+ * @param[in] - i_lWord - 64bit long word
+ *
+ * @return - uint32_t word
+ */
+ inline uint32_t lower32BWord(uint64_t i_lWord)
+ {
+ return (uint32_t)(MASK_ZERO_H32B_UINT64(i_lWord));
+ }
+
+} // namespace SBE
+#endif //SBE_UTIL_H
diff --git a/src/sbefw/vector b/src/sbefw/vector
new file mode 100644
index 00000000..5929f85f
--- /dev/null
+++ b/src/sbefw/vector
@@ -0,0 +1,397 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/vector $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef stl_vector
+#define stl_vector
+
+/**
+ * @file vector
+ * @brief simple stl vector template class declaration.
+ */
+
+#include <stddef.h>
+
+#if !defined( __STDC_LIMIT_MACROS)
+#define __STDC_LIMIT_MACROS
+#endif
+#include <stdint.h>
+#include <pool.H>
+#include <assert.h>
+#include <new>
+namespace std
+{
+
+ /**
+ * @class vector
+ * subset of stl vector
+ * @note Does not support allocators, reverse iterators.
+ */
+ template <class T>
+ class vector
+ {
+ public:
+
+ typedef T * iterator;
+ typedef const T * const_iterator;
+ typedef T & reference;
+ typedef const T & const_reference;
+ typedef size_t size_type;
+ typedef T value_type;
+ typedef T * pointer;
+ typedef const T * const_pointer;
+
+ protected:
+
+ pointer iv_start __attribute__ ((aligned (8)));
+ pointer iv_finish;
+ SBEVECTORPOOL::vectorMemPool_t *iv_poolPtr;
+ public:
+
+ /**
+ * Constructor default
+ * @post The vector is created with storage of
+ * G_BLOCKSIZE bytes.
+ */
+ explicit vector(void)
+ {
+ iv_poolPtr = SBEVECTORPOOL::allocMem();
+ assert ( NULL != iv_poolPtr)
+ iv_start = ( T* )iv_poolPtr->data;
+ iv_finish = iv_start;
+ }
+
+
+ /**
+ * MOVE COPY CTOR create a vector from another vector
+ * @param[in] x source vector
+ * @post Vector of x.size() is created from x with same
+ * memory.
+ * size() == capacity() == x.size()
+ * @note move Copy construtor willuse shallow copy. So input
+ * as well as output vector will point to same data
+ */
+ vector(const vector<T>&& x)
+ {
+ iv_start = x.iv_start;
+ iv_finish = x.iv_finish;
+ iv_poolPtr = x.iv_poolPtr;
+ iv_poolPtr->refCount++;
+ }
+
+ /**
+ * Reserve space for atleast n elements
+ * @param[in] n Number of elements
+ * @note We are having fixed size vectors in ppe. Defining
+ * this function to avoid compile issues in standard
+ * library. This function is noop for less than 512
+ * bytes requirement. For more than 512 bytes, it will
+ * assert.
+ */
+ void reserve(size_type n)
+ {
+ assert(n < max_size());
+ return;
+ }
+ /**
+ * DTOR
+ * @post Storage released
+ */
+ __attribute__ ((always_inline))
+ ~vector()
+ {
+ clear(); // call dtors
+ SBEVECTORPOOL::releaseMem(iv_poolPtr);
+ }
+
+ /**
+ * Move Assignment operator.
+ * @param[in] x A vector.
+ * @return A vector (for the purpose of multiple assigns).
+ * @pre None.
+ * @post *this == x, this->capacity() == x.size().
+ * All previously obtained iterators are invalid.
+ */
+ vector<T>& operator=(const vector<T>&& x)
+ {
+ // Just check here for pool to make sure
+ // input vector and current vector are not same;
+ if( iv_poolPtr != x.iv_poolPtr)
+ {
+ clear();
+ SBEVECTORPOOL::releaseMem(iv_poolPtr);
+ iv_start = x.iv_start;
+ iv_finish = x.iv_finish;
+ iv_poolPtr = x.iv_poolPtr;
+ iv_poolPtr->refCount++;
+ }
+ return(*this);
+ }
+
+ // Iterators --------------------
+
+ /**
+ * Get iterator to the first vector element
+ * @return iterator of rist vector element
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ iterator begin()
+ {
+ return (iv_start);
+ }
+
+ /**
+ * Get const_iterator to the first vector element
+ * @return const_iterator of rist vector element
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ const_iterator begin() const
+ {
+ return (iv_start);
+ }
+
+ /**
+ * Get iterator to the last vector element + 1
+ * @return iterator
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ iterator end()
+ {
+ return (iv_finish);
+ }
+
+ /**
+ * Get const_iterator to the last vector element + 1
+ * @return const_iterator
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ const_iterator end() const
+ {
+ return (iv_finish);
+ }
+
+ // Capacity -----------------------------------------------
+
+ /**
+ * Get the number of elements in the container
+ * @return number of elements in the container
+ */
+ __attribute__ ((always_inline))
+ size_type size() const
+ {
+ return(iv_finish - iv_start);
+ }
+
+ /**
+ * Return the maximum potential size the container could reach.
+ * @return number of the maximum element count this container
+ * could reach
+ */
+ __attribute__ ((always_inline))
+ size_type max_size() const
+ {
+ return SBEVECTORPOOL::G_BLOCKSIZE/(sizeof(T));
+ }
+
+ /**
+ * Query for empty container
+ * @return bool, true if size()==0 else false.
+ * @pre none
+ * @post none
+ */
+ __attribute__ ((always_inline))
+ bool empty() const
+ {
+ return(size() == 0);
+ }
+
+ // - Element Access -----------------------------------
+
+ /**
+ * Access a mutable reference to an element in the container
+ * @param An index into the vector
+ * @return A reference to an element
+ * @pre 0 <= n < size()
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ reference operator[](size_type n)
+ {
+ assert(n < size());
+ return(*(iv_start + n));
+ }
+
+ /**
+ * Access a mutable reference to an element in the container
+ * @param[in] index An index into the vector
+ * @return A reference to an element
+ * @pre 0 <= n < size()
+ * @post None.
+ * @note no exception handling
+ */
+ __attribute__ ((always_inline))
+ reference at(size_type index)
+ {
+ assert(index < size());
+ return(*(iv_start + index));
+ }
+
+ /**
+ * Get an immutable reference to an element in the container
+ * @param[in] index An index into the vector
+ * @return A const_reference to an object or type T
+ * @pre 0 <= n < size()
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ const_reference operator[](size_type index) const
+ {
+ assert(index < size());
+ return(*(iv_start + index));
+ }
+
+ /**
+ * Get an immutable reference to an element in the container
+ * @param[in] index An index into the vector
+ * @return A const_reference to an object or type T
+ * @pre 0 <= n < size()
+ * @post None.
+ * @note no exception handling
+ */
+ __attribute__ ((always_inline))
+ const_reference at(size_type index) const
+ {
+ assert(index < size());
+ return(*(iv_start + index));
+ }
+
+ /**
+ * Get a mutable reference to the first element in the container
+ * @return reference to first element
+ * @pre none
+ * @post None
+ */
+ __attribute__ ((always_inline))
+ reference front()
+ {
+ return *iv_start;
+ }
+
+ /**
+ * Get an Immutable reference to the first element in the
+ * container
+ * @return const_reference to first element
+ * @pre none
+ * @post None
+ */
+ __attribute__ ((always_inline))
+ const_reference front() const
+ {
+ return *iv_start;
+ }
+
+ /**
+ * Get a mutable reference to the last element in the container
+ * @return reference to last element
+ * @pre none
+ * @post None
+ */
+ __attribute__ ((always_inline))
+ reference back()
+ {
+ return *(iv_finish-1);
+ }
+
+ /**
+ * Get an Immutable reference to the last element in the
+ * container
+ * @return reference to last element
+ * @pre none
+ * @post None
+ */
+ __attribute__ ((always_inline))
+ const_reference back() const
+ {
+ return *(iv_finish-1);
+ }
+
+ /**
+ * Add element to the back of the container
+ * @param[in] x reference to object used to create new element
+ * @pre none
+ * @post All previously obtained iterators are invalid.
+ */
+ __attribute__ ((always_inline))
+ void push_back(const T& x)
+ {
+ assert(max_size() > size());
+ new (iv_finish++) T(x);
+ }
+
+ /**
+ * Clear the vector
+ * @pre none.
+ * @post size() = 0, All previously obtained iterators are
+ * invalid
+ * @note capacity unchanged
+ */
+ void clear ()
+ {
+ while(iv_finish != iv_start)
+ {
+ --iv_finish;
+ (iv_finish)->~T();
+ }
+ }
+
+ /*
+ * Assign new content to the vector object
+ * @param[in] n number of elements to assign
+ * @param[in] x reference to element to copy in
+ */
+ void assign ( size_type n, const T& x)
+ {
+ assert(n < max_size());
+ clear();
+ for ( ; n> 0; n--)
+ push_back( x);
+ }
+
+ private:
+ vector(const vector<T>& x);
+ vector<T>& operator=(const vector<T>& x);
+};
+
+}; // end namespace std
+
+
+#endif
+/* vim: set filetype=cpp : */
OpenPOWER on IntegriCloud