summaryrefslogtreecommitdiffstats
path: root/src/sbefw
diff options
context:
space:
mode:
authorRaja Das <rajadas2@in.ibm.com>2017-11-09 05:14:05 -0600
committerSachin Gupta <sgupta2m@in.ibm.com>2018-04-09 11:52:15 -0400
commit6efa7f05b7f4456ada99224b2b5b68274abac902 (patch)
tree03f4ab02038b5994ead5fd5cb9ae156648edf339 /src/sbefw
parent6d4731168c57c0c31bd1f9c29386c9587e0e1ea5 (diff)
downloadtalos-sbe-6efa7f05b7f4456ada99224b2b5b68274abac902.tar.gz
talos-sbe-6efa7f05b7f4456ada99224b2b5b68274abac902.zip
S0/S1 enabled for SBE
RTC: 159756 Change-Id: I01532623ea575fa669be28b3c19bac9c8cd7e7b4 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/49474 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Shakeeb A. Pasha B K <shakeebbk@in.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'src/sbefw')
-rw-r--r--src/sbefw/app/power/chipop_table.C1
-rw-r--r--src/sbefw/app/power/sbecmdmpipl.C243
-rw-r--r--src/sbefw/app/power/sbecmdmpipl.H27
-rw-r--r--src/sbefw/core/corefiles.mk6
-rw-r--r--src/sbefw/core/sbe_sp_intf.H3
-rw-r--r--src/sbefw/core/sbecmdprocessor.C24
-rw-r--r--src/sbefw/core/sbecmdreceiver.C22
-rw-r--r--src/sbefw/core/sbeexeintf.H9
-rw-r--r--src/sbefw/core/sbeirq.C77
-rw-r--r--src/sbefw/core/sbes0handler.C144
-rw-r--r--src/sbefw/core/sbes0handler.H56
11 files changed, 483 insertions, 129 deletions
diff --git a/src/sbefw/app/power/chipop_table.C b/src/sbefw/app/power/chipop_table.C
index 4ba84581..fb0f6ea1 100644
--- a/src/sbefw/app/power/chipop_table.C
+++ b/src/sbefw/app/power/chipop_table.C
@@ -42,7 +42,6 @@
#include "sbecmdtracearray.H"
#include "sbecmdCntrlTimer.H"
#include "sbecmdfastarray.H"
-
#include "core/chipop_handler.H"
#include "app/common/sbecmdgeneric.H"
diff --git a/src/sbefw/app/power/sbecmdmpipl.C b/src/sbefw/app/power/sbecmdmpipl.C
index 47e76bcd..b12453eb 100644
--- a/src/sbefw/app/power/sbecmdmpipl.C
+++ b/src/sbefw/app/power/sbecmdmpipl.C
@@ -81,6 +81,71 @@ static const uint32_t ISTEP_MINOR_START = 1;
static const uint32_t ISTEP4_MAX_SUBSTEPS = 34;
static const uint32_t ISTEP5_MAX_SUBSTEPS = 2;
+ReturnCode startMpiplIstepsExecute(void)
+{
+ #define SBE_FUNC " startMpiplIstepsExecute "
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode fapiRc = FAPI2_RC_SUCCESS;
+
+ uint32_t minor = 1;
+ do
+ {
+ fapiRc = sbeExecuteIstep(SBE_ISTEP_MPIPL_START, minor);
+ if(fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "Failed in StartMpipl Minor Isteps[%d]", minor);
+ break;
+ }
+ ++minor;
+ }while(minor<=MPIPL_START_MAX_SUBSTEPS);
+
+ SBE_EXIT(SBE_FUNC);
+ return fapiRc;
+ #undef SBE_FUNC
+}
+
+static const uint8_t g_continuempipl_isteps[3][3] = {
+ // Major Num, Minor Start, Minor End
+ {SBE_ISTEP_MPIPL_CONTINUE, ISTEP_MINOR_START, MPIPL_CONTINUE_MAX_SUBSTEPS},
+ {SBE_ISTEP4, ISTEP_MINOR_START, ISTEP4_MAX_SUBSTEPS},
+ {SBE_ISTEP5, ISTEP_MINOR_START, ISTEP5_MAX_SUBSTEPS}};
+
+
+ReturnCode continueMpiplIstepsExecute(const sbeRole i_sbeRole)
+{
+ #define SBE_FUNC " continueMpiplIstepsExecute "
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode fapiRc = FAPI2_RC_SUCCESS;
+
+ // Loop through isteps
+ for( auto istep : g_continuempipl_isteps )
+ {
+ for(uint8_t minor = istep[1]; minor <= istep[2]; minor++)
+ {
+ fapiRc = sbeExecuteIstep(istep[0], minor);
+ if(fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "Failed in Master ContinueMpipl Isteps "
+ "Major[%d] Minor[%d]", istep[0], minor);
+ break;
+ }
+ }
+ if(fapiRc != FAPI2_RC_SUCCESS)
+ {
+ break;
+ }
+ if(i_sbeRole == SBE_ROLE_SLAVE)
+ {
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_RUNTIME_EVENT);
+ break;
+ }
+ }
+ SBE_EXIT(SBE_FUNC);
+ return fapiRc;
+ #undef SBE_FUNC
+}
+
///////////////////////////////////////////////////////////////////////
// @brief sbeEnterMpipl Sbe enter MPIPL function
//
@@ -90,49 +155,42 @@ uint32_t sbeEnterMpipl(uint8_t *i_pArg)
{
#define SBE_FUNC " sbeEnterMpipl "
SBE_ENTER(SBE_FUNC);
- uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
- uint32_t l_fapiRc = FAPI2_RC_SUCCESS;
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ ReturnCode fapiRc = FAPI2_RC_SUCCESS;
uint32_t len = 0;
- sbeRespGenHdr_t l_respHdr;
- l_respHdr.init();
- sbeResponseFfdc_t l_ffdc;
+
+ sbeResponseFfdc_t ffdc;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
do
{
// Dequeue the EOT entry as no more data is expected.
- l_rc = sbeUpFifoDeq_mult (len, NULL);
- CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ rc = sbeUpFifoDeq_mult (len, NULL);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(rc);
- uint32_t l_minor = 1;
- do
+ fapiRc = startMpiplIstepsExecute();
+ bool checkstop = isSystemCheckstop();
+ if((fapiRc != FAPI2_RC_SUCCESS) || checkstop)
{
- l_fapiRc = sbeExecuteIstep(SBE_ISTEP_MPIPL_START, l_minor);
- bool checkstop = isSystemCheckstop();
- if((l_fapiRc != FAPI2_RC_SUCCESS) || checkstop)
+ SBE_ERROR(SBE_FUNC "Failed in Mpipl Start in ChipOp Mode");
+ if(checkstop)
{
- SBE_ERROR(SBE_FUNC "Failed in Mpipl Start in ChipOp Mode "
- "Minor: %d", l_minor);
- if(checkstop)
- {
- l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
- SBE_SEC_SYSTEM_CHECKSTOP);
- }
- else
- {
- l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
- SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
- l_ffdc.setRc(l_fapiRc);
- }
- // reset attribute. We do not want to reset register, so do not
- // use setMpIplMode
- uint8_t isMpipl = 0;
- PLAT_ATTR_INIT(ATTR_IS_MPIPL, Target<TARGET_TYPE_SYSTEM>(),
- isMpipl);
- break;
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_SYSTEM_CHECKSTOP);
}
- ++l_minor;
- }while(l_minor<=MPIPL_START_MAX_SUBSTEPS);
-
+ else
+ {
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ }
+ // reset attribute. We do not want to reset register, so do not
+ // use setMpIplMode
+ uint8_t isMpipl = 0;
+ PLAT_ATTR_INIT(ATTR_IS_MPIPL, Target<TARGET_TYPE_SYSTEM>(), isMpipl);
+ break;
+ }
}while(0);
// Create the Response to caller
@@ -140,12 +198,12 @@ uint32_t sbeEnterMpipl(uint8_t *i_pArg)
{
// 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);
- l_rc = sbeDsSendRespHdr( l_respHdr, &l_ffdc);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(rc);
+ rc = sbeDsSendRespHdr( respHdr, &ffdc);
}while(0);
SBE_EXIT(SBE_FUNC);
- return l_rc;
+ return rc;
#undef SBE_FUNC
}
@@ -158,66 +216,42 @@ uint32_t sbeContinueMpipl(uint8_t *i_pArg)
{
#define SBE_FUNC " sbeContinueMpipl "
SBE_ENTER(SBE_FUNC);
- uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ ReturnCode fapiRc = FAPI2_RC_SUCCESS;
uint32_t len = 0;
- ReturnCode l_fapiRc = FAPI2_RC_SUCCESS;
- sbeResponseFfdc_t l_ffdc;
- sbeRespGenHdr_t l_respHdr;
- l_respHdr.init();
+ sbeResponseFfdc_t ffdc;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
do
{
// Dequeue the EOT entry as no more data is expected.
- l_rc = sbeUpFifoDeq_mult (len, NULL);
- CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ rc = sbeUpFifoDeq_mult (len, NULL);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(rc);
- sbeRole l_sbeRole = SbeRegAccess::theSbeRegAccess().isSbeSlave() ?
+ sbeRole sbeRole = SbeRegAccess::theSbeRegAccess().isSbeSlave() ?
SBE_ROLE_SLAVE : SBE_ROLE_MASTER;
- // Run isteps
- const uint8_t isteps[][3] = {
- // Major Num, Minor Start, Minor End
- {SBE_ISTEP_MPIPL_CONTINUE, ISTEP_MINOR_START, MPIPL_CONTINUE_MAX_SUBSTEPS},
- {SBE_ISTEP4, ISTEP_MINOR_START, ISTEP4_MAX_SUBSTEPS},
- {SBE_ISTEP5, ISTEP_MINOR_START, ISTEP5_MAX_SUBSTEPS}};
- // Loop through isteps
- for( auto istep : isteps)
+ fapiRc = continueMpiplIstepsExecute(sbeRole);
+ bool checkstop = isSystemCheckstop();
+ if((fapiRc != FAPI2_RC_SUCCESS) || checkstop)
{
- // This is required here to skip the major istep 4/5 in slave
- if((SBE_ROLE_SLAVE == l_sbeRole) &&
- (istep[0] == 4 || istep[0] == 5))
+ SBE_ERROR(SBE_FUNC "Failed in Continue Mpipl in ChipOp Mode, "
+ "SBE Role[%d]", sbeRole);
+ if(checkstop)
{
- (void)SbeRegAccess::theSbeRegAccess().stateTransition(
- SBE_RUNTIME_EVENT);
- continue;
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_SYSTEM_CHECKSTOP);
}
- for(uint8_t l_minor = istep[1]; l_minor <= istep[2]; l_minor++)
- {
- l_fapiRc = sbeExecuteIstep(istep[0], l_minor);
- bool checkstop = isSystemCheckstop();
- if((l_fapiRc != FAPI2_RC_SUCCESS) || checkstop)
- {
- SBE_ERROR(SBE_FUNC "Failed in Mpipl continue in ChipOp "
- "Mode Major [%d] Minor [%d]", istep[0], l_minor);
- if(checkstop)
- {
- l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
- SBE_SEC_SYSTEM_CHECKSTOP);
- }
- else
- {
- l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
- SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
- l_ffdc.setRc(l_fapiRc);
- }
- break;
- }
- }
- if(l_ffdc.getRc() != FAPI2_RC_SUCCESS)
+ else
{
- break;
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ // Async Response to be stored
}
+ break;
}
}while(0);
@@ -228,15 +262,52 @@ uint32_t sbeContinueMpipl(uint8_t *i_pArg)
// Create the Response to caller
// 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)
+ if(SBE_SEC_OPERATION_SUCCESSFUL == rc)
{
- l_rc = sbeDsSendRespHdr( l_respHdr, &l_ffdc);
+ rc = sbeDsSendRespHdr( respHdr, &ffdc);
}
SBE_EXIT(SBE_FUNC);
- return l_rc;
+ return rc;
#undef SBE_FUNC
}
+#ifdef _S0_
+///////////////////////////////////////////////////////////////////////
+// @brief stopClockS0 Sbe StopClock S0 interface function
+//
+// @return RC from the underlying FIFO utility
+///////////////////////////////////////////////////////////////////////
+ReturnCode stopClockS0()
+{
+#define SBE_FUNC "stopClockS0"
+ SBE_ENTER(SBE_FUNC);
+ uint32_t fapiRc = FAPI2_RC_SUCCESS;
+ p9_stopclocks_flags flags;
+
+ p9hcd::P9_HCD_CLK_CTRL_CONSTANTS clk_regions =
+ p9hcd::CLK_REGION_ALL_BUT_PLL_REFR;
+ p9hcd::P9_HCD_EX_CTRL_CONSTANTS ex_select = p9hcd::BOTH_EX;
+
+ flags.clearAll();
+ flags.sync_stop_quad_clks = false;
+ flags.stop_core_clks = true;
+ flags.stop_cache_clks = true;
+
+ SBE_EXEC_HWP(fapiRc, p9_stopclocks_hwp,
+ plat_getChipTarget(),
+ flags,
+ clk_regions,
+ ex_select);
+ if(fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "Failed in StopClock S0S1 Interface");
+ }
+
+ SBE_EXIT(SBE_FUNC);
+ return fapiRc;
+#undef SBE_FUNC
+}
+#endif
///////////////////////////////////////////////////////////////////////
/* @brief Deduce the type of stop clock procedure to call based on
* target and chiplet id combination
diff --git a/src/sbefw/app/power/sbecmdmpipl.H b/src/sbefw/app/power/sbecmdmpipl.H
index 34582b48..adda51eb 100644
--- a/src/sbefw/app/power/sbecmdmpipl.H
+++ b/src/sbefw/app/power/sbecmdmpipl.H
@@ -6,6 +6,7 @@
/* OpenPOWER sbe Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* [+] International Business Machines Corp. */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -32,6 +33,7 @@
#define __SBEFW_SBECMDMPIPL_H
#include <stdint.h>
+#include "sbestates.H"
/**
* @brief Handles Sbe Enter Mpipl chip-op (0xA901)
@@ -60,4 +62,29 @@ uint32_t sbeContinueMpipl(uint8_t *i_pArg);
*/
uint32_t sbeStopClocks(uint8_t *i_pArg);
+/**
+ * @brief Handles Sbe Start MPIPL iSteps
+ *
+ * @return Rc from the FIFO access utility
+ */
+fapi2::ReturnCode startMpiplIstepsExecute(void);
+
+/**
+ * @brief Handles Sbe Continue MPIPL iSteps based on Master/Slave SBE
+ *
+ * @param[in] i_sbeRole Master/Slave SBE
+ *
+ * @return Rc from the FIFO access utility
+ */
+fapi2::ReturnCode continueMpiplIstepsExecute(const sbeRole i_sbeRole);
+
+#ifdef _S0_
+/**
+ * @brief Handles Sbe Stop Clock (Core/Cache) procedure in S0 context
+ *
+ * @return Rc from the FIFO access utility
+ */
+fapi2::ReturnCode stopClockS0();
+#endif
+
#endif /* __SBEFW_SBECMDMPIPL_H */
diff --git a/src/sbefw/core/corefiles.mk b/src/sbefw/core/corefiles.mk
index 4ab1450c..3b3bf233 100644
--- a/src/sbefw/core/corefiles.mk
+++ b/src/sbefw/core/corefiles.mk
@@ -44,6 +44,9 @@ COREPIBMEM-CPP-SOURCES += sbeSecureMemRegionManager.C
COREPIBMEM-CPP-SOURCES += sbeSecurity.C
COREPIBMEM-CPP-SOURCES += chipop_handler.C
COREPIBMEM-CPP-SOURCES += ipl.C
+ifeq ($(SBE_S0_SUPPORT), 1)
+COREPIBMEM-CPP-SOURCES += sbes0handler.C
+endif
COREPIBMEM-C-SOURCES =
COREPIBMEM-S-SOURCES =
@@ -52,6 +55,9 @@ COREPIBMEM_OBJECTS = $(COREPIBMEM-C-SOURCES:.c=.o) $(COREPIBMEM-CPP-SOURCES:.C=.
# seeprom objects
CORESEEPROM-CPP-SOURCES = sbeSecureMemRegionManager.C
+ifeq ($(SBE_S0_SUPPORT), 1)
+CORESEEPROM-CPP-SOURCES += sbes0handler.C
+endif
CORESEEPROM-C-SOURCES =
CORESEEPROM-S-SOURCES =
diff --git a/src/sbefw/core/sbe_sp_intf.H b/src/sbefw/core/sbe_sp_intf.H
index ae4876e9..e35ac4be 100644
--- a/src/sbefw/core/sbe_sp_intf.H
+++ b/src/sbefw/core/sbe_sp_intf.H
@@ -222,6 +222,9 @@ enum sbeSecondaryResponse
SBE_SEC_DMT_TIMEOUT = 0x21,
SBE_SEC_SYSTEM_CHECKSTOP = 0x22,
SBE_SEC_BLACKLISTED_REG_ACCESS_BLOCKED = 0x23,
+ SBE_SEC_S0_START_MPIPL_FAILED = 0x24,
+ SBE_SEC_S0_STOP_CLOCK_FAILED = 0x25,
+ SBE_SEC_S0_CONTINUE_MPIPL_FAILED = 0x26,
};
/**
diff --git a/src/sbefw/core/sbecmdprocessor.C b/src/sbefw/core/sbecmdprocessor.C
index 1c1f2698..a70bb4eb 100644
--- a/src/sbefw/core/sbecmdprocessor.C
+++ b/src/sbefw/core/sbecmdprocessor.C
@@ -48,6 +48,11 @@
#include "sbeglobals.H"
#include "core/chipop_handler.H"
#include "core/ipl.H"
+
+#ifdef _S0_
+#include "sbes0handler.H"
+#endif
+
using namespace fapi2;
// Forward declaration for performAttrSetup
@@ -325,6 +330,16 @@ void sbeSyncCommandProcessor_routine(void *i_pArg)
SBE_GLOBAL->sbeIntrSource.setIntrSource(SBE_PROC_ROUTINE,
SBE_INTERFACE_FIFO);
}
+#ifdef _S0_
+ else if ( SBE_GLOBAL->sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_S0) )
+ {
+ SBE_GLOBAL->sbeIntrSource.setIntrSource(SBE_PROC_ROUTINE,
+ SBE_INTERFACE_S0);
+ l_rc = sbeHandleS0((uint8_t *)i_pArg);
+ break;
+ }
+#endif
else // SBE_INTERFACE_FIFO_RESET or SBE_INTERFACE_UNKNOWN
{
SBE_ERROR(SBE_FUNC"Unexpected interrupt communicated to the "
@@ -380,6 +395,15 @@ void sbeSyncCommandProcessor_routine(void *i_pArg)
pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
pk_irq_enable(SBE_IRQ_SBEFIFO_RESET);
}
+#ifdef _S0_
+ else if ( SBE_GLOBAL->sbeIntrSource.isSet(SBE_PROC_ROUTINE, SBE_INTERFACE_S0) )
+ {
+ // No Response to handle here, Async response
+ // Enable Host interrupt
+ SBE_GLOBAL->sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,SBE_INTERFACE_S0);
+ pk_irq_enable(SBE_IRQ_INTR0);
+ }
+#endif
} while(true); // Thread always exists
SBE_EXIT(SBE_FUNC);
}
diff --git a/src/sbefw/core/sbecmdreceiver.C b/src/sbefw/core/sbecmdreceiver.C
index 15017a47..6ed11c37 100644
--- a/src/sbefw/core/sbecmdreceiver.C
+++ b/src/sbefw/core/sbecmdreceiver.C
@@ -43,6 +43,10 @@
#include "sbeutil.H"
#include "sbeglobals.H"
+#ifdef _S0_
+#include "sbes0handler.H"
+#endif
+
#include "core/chipop_handler.H"
//////////////////////////////////////////////////////
@@ -61,7 +65,8 @@ void sbeCommandReceiver_routine(void *i_pArg)
{
// @TODO via RTC: 128944
// Read Scratchpad
- // Wait for new data in FIFO or FIFO reset interrupt or PSU interrupt
+ // Wait for new data in FIFO or FIFO reset interrupt or PSU interrupt or
+ // s0/s1 interrupt
int l_rcPk = pk_semaphore_pend (&SBE_GLOBAL->sbeSemCmdRecv, PK_WAIT_FOREVER);
do
@@ -171,6 +176,21 @@ void sbeCommandReceiver_routine(void *i_pArg)
l_command = SBE_GLOBAL->sbeFifoCmdHdr.command;
} // end else if loop for FIFO interface chipOp handling
+#ifdef _S0_
+ // Received S0 interrupt
+ else if ( SBE_GLOBAL->sbeIntrSource.isSet(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_S0) )
+ {
+ //Clear interrupt source bit PERV_SB_CS_SCOM
+ clearS0interrupt();
+ //Clear the Interrupt Source bit for S0
+ SBE_GLOBAL->sbeIntrSource.clearIntrSource(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_S0);
+ curInterface = SBE_INTERFACE_S0;
+ // Break out from Command/Class validation, post to processor
+ break;
+ }
+#endif
// Any other FIFO access issue
if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
{
diff --git a/src/sbefw/core/sbeexeintf.H b/src/sbefw/core/sbeexeintf.H
index eaeab51c..dc4f6936 100644
--- a/src/sbefw/core/sbeexeintf.H
+++ b/src/sbefw/core/sbeexeintf.H
@@ -87,10 +87,13 @@ enum sbeThreadStackSize
*/
typedef enum
{
- SBE_INTERFACE_UNKNOWN = 0x00,
- SBE_INTERFACE_FIFO = 0x01,
- SBE_INTERFACE_PSU = 0x02,
+ SBE_INTERFACE_UNKNOWN = 0x00,
+ SBE_INTERFACE_FIFO = 0x01,
+ SBE_INTERFACE_PSU = 0x02,
SBE_INTERFACE_FIFO_RESET = 0x04,
+#ifdef _S0_
+ SBE_INTERFACE_S0 = 0x08,
+#endif
} sbeInterfaceSrc_t;
/*
diff --git a/src/sbefw/core/sbeirq.C b/src/sbefw/core/sbeirq.C
index a1d5b72b..c99c459a 100644
--- a/src/sbefw/core/sbeirq.C
+++ b/src/sbefw/core/sbeirq.C
@@ -43,6 +43,8 @@
// - FIFO new data available
// - FIFO reset request
// - PSU new data available
+// - S0 Interrupt
+// - S1 Interrupt
//
// @param[in] i_pArg - Unused
// @param[in] i_irq - IRQ number as defined in sbeirq.h
@@ -73,7 +75,12 @@ void sbe_interrupt_handler (void *i_pArg, PkIrqId i_irq)
SBE_INTERFACE_FIFO_RESET);
pk_irq_disable(SBE_IRQ_SBEFIFO_DATA);
break;
-
+#ifdef _S0_
+ case SBE_IRQ_INTR0:
+ SBE_GLOBAL->sbeIntrSource.setIntrSource(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_S0);
+ break;
+#endif
default:
SBE_ERROR(SBE_FUNC"Unknown IRQ, assert");
assert(0);
@@ -95,61 +102,55 @@ void sbe_interrupt_handler (void *i_pArg, PkIrqId i_irq)
#undef SBE_FUNC
}
+// Interrupts which are available in SBE, in an array
+static uint32_t G_supported_irqs[] = {
+ SBE_IRQ_HOST_PSU_INTR,
+ SBE_IRQ_SBEFIFO_DATA,
+ SBE_IRQ_SBEFIFO_RESET,
+#ifdef _S0_
+ SBE_IRQ_INTR0,
+#endif
+ };
+
+// Create the Vector mask for all the interrupts in SBE,
+// required to call disable/enable with this vector mask
+constexpr uint64_t getVectorMask ( size_t index )
+{
+ return (index >= (sizeof(G_supported_irqs)/sizeof(uint32_t))?
+ 0:STD_IRQ_MASK64(G_supported_irqs[index])|getVectorMask(index + 1));
+}
+
////////////////////////////////////////////////////////////////
// See sbeexeintf.h for more details
////////////////////////////////////////////////////////////////
int sbeIRQSetup (void)
{
#define SBE_FUNC " sbeIRQSetup "
- int l_rc = 0;
- PkIrqId l_irq;
+ int rc = 0;
+ uint64_t vector_mask = getVectorMask(0);
// 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);
+ pk_irq_vec_disable(vector_mask);
- do
+ for(uint32_t cnt=0; cnt<sizeof(G_supported_irqs)/sizeof(uint32_t); cnt++)
{
// 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)
+ rc = pk_irq_handler_set(G_supported_irqs[cnt], sbe_interrupt_handler, NULL);
+ if(rc)
{
+ SBE_ERROR (SBE_FUNC "pk_irq_handler_set failed, IRQ=[0x%02X], "
+ "rc=[%d]", G_supported_irqs[cnt], 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)
+ if(!rc)
{
- SBE_ERROR (SBE_FUNC"pk_irq_handler_set failed, IRQ=[0x%02X], "
- "rc=[%d]", l_irq, l_rc);
+ // Enable the IRQ
+ pk_irq_vec_enable(vector_mask);
}
- return l_rc;
+ return rc;
#undef SBE_FUNC
}
diff --git a/src/sbefw/core/sbes0handler.C b/src/sbefw/core/sbes0handler.C
new file mode 100644
index 00000000..dd16e777
--- /dev/null
+++ b/src/sbefw/core/sbes0handler.C
@@ -0,0 +1,144 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/core/sbes0handler.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* 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/src/sbefw/sbes0handler.C
+ *
+ * @brief This file contains the SBE S0 Handler
+ *
+ */
+
+#include "sbefifo.H"
+#include "sbeSpMsg.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbeFifoMsgUtils.H"
+#include "sberegaccess.H"
+#include "sbefapiutil.H"
+#include "sbecmdiplcontrol.H"
+#include "sbecmdmpipl.H"
+#include "sbeFFDC.H"
+#include "sbes0handler.H"
+
+#include "fapi2.H"
+#include "p9_perv_scom_addresses.H"
+
+using namespace fapi2;
+
+#ifdef __SBEFW_SEEPROM__
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeHandleS0
+//
+// @return RC from the function
+///////////////////////////////////////////////////////////////////////
+uint32_t sbeHandleS0(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeHandleS0 "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ ReturnCode fapiRc = FAPI2_RC_SUCCESS;
+
+ do // Do while for both StartMpipl and ContinueMpipl
+ {
+ fapiRc = startMpiplIstepsExecute();
+ if(fapiRc != FAPI2_RC_SUCCESS)
+ {
+ rc = SBE_SEC_S0_START_MPIPL_FAILED;
+ SBE_ERROR(SBE_FUNC "Failed in Start Mpipl S0 Interface");
+ break;
+ }
+
+ // TODO - RTC: 190585
+ //Core and Cache stop Clock
+ fapiRc = stopClockS0();
+ if(fapiRc != FAPI2_RC_SUCCESS)
+ {
+ rc = SBE_SEC_S0_STOP_CLOCK_FAILED;
+ SBE_ERROR(SBE_FUNC "Failed in Core/Cache StopClock S0 Interface");
+ break;
+ }
+
+ sbeRole sbeRole = SbeRegAccess::theSbeRegAccess().isSbeSlave() ?
+ SBE_ROLE_SLAVE : SBE_ROLE_MASTER;
+
+ if(sbeRole == SBE_ROLE_MASTER)
+ {
+ fapiRc = continueMpiplIstepsExecute(sbeRole);
+ if(fapiRc != FAPI2_RC_SUCCESS)
+ {
+ rc = SBE_SEC_S0_CONTINUE_MPIPL_FAILED;
+ SBE_ERROR(SBE_FUNC "Failed in Continue Mpipl S0 Interface, "
+ "SBE Role[%d]", sbeRole);
+ break;
+ }
+ }
+ }while(0);
+
+ if(rc)
+ {
+ // Async Response to be stored
+ captureAsyncFFDC(SBE_PRI_GENERIC_EXECUTION_FAILURE, rc);
+ }
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+
+#endif // #ifdef __SBEFW_SEEPROM__
+
+#ifndef __SBEFW_SEEPROM__
+
+uint32_t clearS0interrupt()
+{
+ #define SBE_FUNC "clearS0interrupt"
+ SBE_ENTER(SBE_FUNC);
+ uint32_t rc = FAPI2_RC_SUCCESS;
+ // Default Mask bit for S0 Innterrupt, bit 49
+ uint64_t MASK_ALL_AND_MODIFY_BIT = 0xFFFDFFFFFFFFFFFFULL;
+
+ do
+ {
+ Target<TARGET_TYPE_PROC_CHIP > procTgt = plat_getChipTarget();
+ uint64_t data;
+ rc = getscom_abs_wrap (&procTgt, PERV_SB_CS_SCOM, &data);
+ if( rc )
+ {
+ break;
+ }
+ data = data & MASK_ALL_AND_MODIFY_BIT;
+ rc = putscom_abs_wrap (&procTgt, PERV_SB_CS_SCOM, data);
+ if( rc )
+ {
+ break;
+ }
+ }while(0);
+
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+
+#endif // #ifndef __SBEFW_SEEPROM__
+
diff --git a/src/sbefw/core/sbes0handler.H b/src/sbefw/core/sbes0handler.H
new file mode 100644
index 00000000..35aa9d12
--- /dev/null
+++ b/src/sbefw/core/sbes0handler.H
@@ -0,0 +1,56 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/core/sbes0handler.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* 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/src/sbefw/sbes0handler.H
+ *
+ * @brief This file contains the Interfaces for S0 Handlers
+ *
+ */
+
+#ifndef __SBEFW_SBES0HANDLER_H
+#define __SBEFW_SBES0HANDLER_H
+
+#include <stdint.h>
+#include <sbeexeintf.H>
+
+/**
+ * @brief Handles Sbe S0 Interrupt
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the function
+ */
+uint32_t sbeHandleS0(uint8_t *i_pArg);
+
+/**
+ * @brief Clear S0 interrupt source bit in PERV_SB_CS_SCOM
+ *
+ * @param[in] i_pArg Interrupt bit to identify S0
+ *
+ * @return Rc from the function
+ */
+uint32_t clearS0interrupt();
+
+#endif /* __SBEFW_SBES0HANDLER_H */
OpenPOWER on IntegriCloud